uncommon_breed
uncommon_breed

Reputation: 182

ElasticSearch: Exact match on Keyword datatype field with array of values

In ElasticSearch, I have a mapping for an email field and title field as given below:

  {
  "person": {
    "mappings": {
      "_doc": {
         "email": {
           "type": "keyword",
           "boost": 80
          },
          "title": {
          "type": "text",
           "boost": 70
          }
       }
     }
   }
 

Each person can have more than one email address and title. So, I'm storing the values in arrays. I use query_string to search for persons with an email address and/or title. Email address needs to match exactly.

I have indexed a document with the following data. Calling GET person/_search in Kibana will yield the following document in the result.

{
  "took": 0,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 1,
    "hits": [
      {
        "_index": "person",
        "_type": "_doc",
        "_id": "101",
        "_score": 1,
        "_source": {
          "title": """["Actor", "Hero", "Model"]""",
          "email": """["[email protected]", "[email protected]", "[email protected]", "[email protected]"]""",
          "SEARCH_ENTITY": "PERSON"
        }
      }
    ]
  }
}

Now when I add some email search parameter I don't get the document back in the result. Remember email is of type keyword.

Request:

GET person/_search
{
  "query" : {
    "query_string" : {
      "query" : "SEARCH_ENTITY:PERSON AND (email: ([email protected]))"
    }
  }
}

Response:

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 0,
    "max_score": null,
    "hits": []
  }
}

But the same kind of query works for title field which is of type text.

Request:

GET person/_search
{
  "query" : {
    "query_string" : {
      "query" : "SEARCH_ENTITY:PERSON AND (title: ((actor)))"
    }
  }
}

Response:

{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 20.137747,
    "hits": [
      {
        "_index": "person",
        "_type": "_doc",
        "_id": "101",
        "_score": 20.137747,
        "_source": {
           "ID": "101",
           "title": """["Actor", "Hero", "Model"]""",
           "email": """["[email protected]", "[email protected]", "[email protected]", "[email protected]"]"""
         }
      }
    ]
  }
}
       

Can someone tell me what I need to do to make this work for email field which is of keyword type?

Note: If I store only one email address without using an array, it works fine.

Thanks.

Upvotes: 0

Views: 444

Answers (1)

Joe - Check out my books
Joe - Check out my books

Reputation: 16943

Make sure you parse the json array strings in title and email like so before you index your docs:

POST person/_doc/101
{
  "title": [
    "Actor",
    "Hero",
    "Model"
  ],
  "email": [
    "[email protected]",
    "[email protected]",
    "[email protected]",
    "[email protected]"
  ],
  "SEARCH_ENTITY": "PERSON"
}

Nothing needs to be changed about the mapping -- just the field values.

Upvotes: 1

Related Questions