DEV Community

loading...
Cover image for Search UI GraphQL API with Elasticsearch & Searchkit

Search UI GraphQL API with Elasticsearch & Searchkit

Joseph McElroy
・4 min read

This tutorial will help you build quickly a developer friendly GraphQL API for Elasticsearch.

Searchkit was born from the frustrations of using Elasticsearch for building great search experiences. Its really powerful but can be really challenging to get the most out of it. Searchkit focuses on configuring search features that make up a great search experience like Facets, Highlighting, Sorting, querying without needing to have deep knowledge in Elasticsearch.

This tutorial will take you through the steps to building a developer friendly Search API using Elasticsearch, GraphQL, Apollo Server and AWS Lambda.

See a working demo of Searchkit API for movies https://demo.searchkit.co/api/graphql which powers https://demo.searchkit.co/

Indexing Data

First we will index a sample dataset into Elasticsearch with @searchkit/cli. Start by downloading the example indexer project.

curl https://codeload.github.com/searchkit/searchkit/tar.gz/next | tar -xz --strip=2 searchkit-next/examples/indexer
Enter fullscreen mode Exit fullscreen mode

Start by creating a new folder inside of indexer which contains a sample dataset in data.json and a config.ts file

image

and then add inside of config.ts the configuration you require.

import data from './data.json'
import { withConfig, toNumber, splitComma, toDate } from '@searchkit/cli'

withConfig({
  index: 'imdb_movies', // the elasticsearch index name
  host: "http://localhost:9200", // host url for elasticsearch
  source: data, // Array of raw documents sample data.
  fields: [
    {
      fieldName: 'type',  // name of field. Must be lowercase
      stored: true, // fields you want returned in the API. 
      facet: true,  // If you want the value to be used as a facet
      searchable: true // If you want the field to be searchable within query
      type: 'integer' // Optional. Default is keyword. Can be `integer`, `date` or `float`
      sourceOptions: { 
        path: 'Type' // Used in indexing step with source dataset. The key for the field value source. 
        transform: (str, doc) => {
          return str.toUppercase()
        } // Optional. Function to provide transformation from source value to document field value 
      }
    }
  ]
})

Enter fullscreen mode Exit fullscreen mode

Add the fields you require (more information on the how to use the cli in Setup Indexing document)

Then update a target in package.json to run the command

image

and then run the command.

image

You will be asked the following options:

Generate Example Searchkit Config?

If yes, CLI will generate a file in current working directory called skConfig.md. This will provide you an elasticsearch mapping file and an example searchkit config, based on the field definitions within config.ts

Host detected. Destroy index and reinsert index mapping?

If yes, will recreate the elasticsearch index

Source detected. Insert documents into ES host?

If yes, will index the documents into elasticsearch

Once you indexed the sample dataset into elasticsearch with the correct types, check to see if you see the data in your elasticsearch instance

image

Building the GraphQL API with AWS Lambda Serverless and Searchkit

Setup the Project

Start by downloading the aws lambda example project

curl https://codeload.github.com/searchkit/searchkit/tar.gz/next | tar -xz --strip=2 searchkit-next/examples/aws-lambda
yarn
yarn global add serverless
Enter fullscreen mode Exit fullscreen mode

then install the dependencies via yarn and install serverless globally

Updating the Searchkit API configuration

in the indexer folder, the CLI will generate an example configuration (skConfig.md) for you.

image

This is generated based on your fields you specified so may need slight changes to reflect your requirements.

You can see all the different types of facets in the API documentation

Copy and update the configuration and GraphQL types in handler.js

image

Then you should be able to run the lambda locally with serverless offline

serverless offline
Enter fullscreen mode Exit fullscreen mode

and visit the graphql playground on http://localhost:3000/dev/graphql

Should everything be successful, you should be able to make a result hits query

{
  results {
    hits {
      items {
        id
        ... on ResultHit {
          fields {
            id
            name
            designerName
            price
            colour
          }
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

image

Once you're happy, you should be able to push up the lambda to AWS with serverless

Using the GraphQL API

image

Now here are some example queries:

Showing Facets and applying filters

{
  results(filters: [{ identifier: "colour", value: "Beige"}]) {
    facets {
      identifier
      label
      type
      display
      entries {
        id
        label
        count
        isSelected
      }
    }
    hits {
      items {
        id
        ... on ResultHit {
          fields {
            id
            name
            designerName
            price
            colour
          }
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Search Query

{
  results(query: "jacket", filters: [{ identifier: "colour", value: "Beige"}]) {
    facets {
      identifier
      label
      type
      display
      entries {
        id
        label
        count
        isSelected
      }
    }
    hits {
      items {
        id
        ... on ResultHit {
          fields {
            id
            name
            designerName
            price
            colour
          }
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Facet filter Search

{
    results(filters: []) {
      facet(identifier: "colour", query: "re") {
        identifier
        label
        entries {
          id
          label
          count
        }
      }
    }
  }
Enter fullscreen mode Exit fullscreen mode

Summary

{
    results(filters: [{ identifier: "colour", value: "red"}]) 
    {
      summary {
        total
        appliedFilters {
          id
          identifier
          label
          display
        }
        query
        sortOptions {
          id
          label
        }
      }
    }
  }
Enter fullscreen mode Exit fullscreen mode

and more information on Searchkit API capabilities on the documentation site

Integrating

React

Searchkit also provides React UI components. Read more information on how to use the out of the box react components or build your own components

Other frameworks like Vue, Svelte

See more information on using web apollo client for other frameworks here

Native iOS and Android

Apollo provides an iOS client to perform GraphQL queries

iOS Client
Android Client

Discussion (0)