Remsy Schmilinsky
Remsy Schmilinsky

Reputation: 23

Elastic search: exact match query on string array

Given this document:

{"name": "Perfect Sunny-Side Up Eggs","ingredientList": ["canola oil","eggs"]}

How can I build a query in elastic search to return exact matches on a string array given query term "oil eggs", so far this it what I have, but it returns other irrelevant documents:

POST /recipes/recipe/_search
{
   "query": {
      "match": {
         "ingredientList": {
            "query": [
               "oil",
               "eggs"
            ],
            "operator": "and"
         }
      }
   }
}

for instance, this document is returned but it doesn't contain "oil". Results should only contain "oil" and "eggs":

{"name": "Quick Baked French Toast","ingredientList": ["butter","cinnamon raisin bread","eggs"]}

Upvotes: 1

Views: 7225

Answers (2)

Tanmay
Tanmay

Reputation: 31

Elastic dont have API to exact match array. But same can be achieved using two methods:

  1. Using multiple must blocks (not preferred)

  2. Using terms set query and script

     "query": {
       "bool": {
         "must": [
           {
             "terms_set": {
               "ingredientList": {
                 "terms": ingredients,
                 "minimum_should_match_script": {
                   "source": "Math.min(params.num_terms, {})".format(len(ingredients))
                 }
               }
             }
           },
           {
             "script": {
               "script": {
                 "inline": "doc['ingredientList'].length == params.list_length",
                 "lang": "painless",
                 "params": {
                   "list_length": len(ingredients)
                 }
               }
             }
           }
         ]
       }
     }
    

Upvotes: 3

fylie
fylie

Reputation: 1715

Your query will look like this:

{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "ingredientList": "oil"
          }
        },
        {
          "term": {
            "ingredientList": "eggs"
          }
        }
      ]
    }
  }
}

Gives me the results:

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 1.0,
    "hits" : [ {
      "_index" : "ingredients",
      "_type" : "recipe",
      "_id" : "AVeprXFrNutW6yNguPqp",
      "_score" : 1.0,
      "_source" : {
        "name" : "Perfect Sunny-Side Up Eggs",
        "ingredientList" : [ "canola oil", "eggs" ]
      }
    } ]
  }
}

Upvotes: 5

Related Questions