How we connected Elastic Search to dgraph

We wanted to perform search queries using ElasticSearch and we didn’t want users to query Elasticsearch directly so we decided to make requests with dgraph using custom directive:

Define a schema that matches the result of elastic search

Here is the schema you need:

type ElasticResult @remote {
  took: Int
  timed_out: Boolean
  _shards: Shard_Data
  hits: Hits
}

type Shard_Data @remote {
  total: Int
  successful: Int
  skipped: Int
  failed: Int
}

type Hits @remote {
  max_score: Float
  hits: [Hit]
}

type Hit @remote {
  _index: String
  _source: Doc
}

# This is the structure of your data in ElasticSearch
type Doc @remote {
  EpisodeID: String
  type: String
  title: String
  tags: String
}

Prepare authorization header

ElasticSearch uses a username password authentication and we can use pass it by using proper authorization header. You can use this link or postman to generate an authorization header based on your username and password:
For example in Postman you can use Basic Auth and enter your username and password:

After doing this Postman will generate Authorization header for you:

We will use this header to make requests to ElasticSearch.

Implement Query

We need to make an external http request so we need custom directive Also we need secret headers to pass the authorization header we have to ElasticSearch server. If you look at the document of custom headers you can see that we can pass this header using # Dgraph.Secret and secretHeaders.

Also I have used first and offset parameters similar to autogenerated queries to tell ElasticSearch how many documents I want.
We have another argument which is phrase that we are searching for it.

The return type is ElasticSearch that we implemented in first section.

type Query {
  ElasticSearch(
    first: Int = 30
    offset: Int = 0
    phrase: String!
  ): ElasticResult
    @custom(
      http: {
        url: "https://your_elastic_server_address/your_index/_search"
        method: POST
        secretHeaders: ["Authorization:Elastic-Search-Token"]
        body: "{query: {match: {name_of_your_field_in_elasticsearch: \"$phrase\"}},size: $first,from: $offset}"
      }
    )
}

# Dgraph.Secret Elastic-Search-Token "Basic ZWxhc3RpYzo3NjgwcTBRR00NEhTMGZoFUEI2WEQ="

Execute Query

After loading this schema we can send a query like this:

query search {
     ElasticSearch(offset: 0, first: 2, phrase: "mySearchPhrase") {
          took
          timed_out
          hits {
               max_score
               hits {
                    _index
                    _source {
# These are your fields from elastic search
                         title
                         tags
                         type
                    }
               }
          }
     }
}

Let me know if I can improve this doc and if I can put it in a better place.

7 Likes