Search code examples
databaseelasticsearchsearchelasticsearch-dsl

Fixing a Simple Elasticsearch Query


I have below data:

{
   "results":[
      {
         "ID":"1",
         "products":[
            {
               "product":"car",
               "number":"5"
            },
            {
               "product":"computer",
               "number":"212"
            }
         ]
      },
      {
         "ID":"2",
         "products":[
            {
               "product":"car",
               "number":"9"
            },
            {
               "product":"computer",
               "number":"463"
            },
            {
               "product":"bicycle",
               "number":"5"
            }
         ]
      }
   ]
}

And my query is below:

{  
   "query":{  
      "bool":{  
         "must":[  
            {  
               "wildcard":{  
                  "results.products.product":"*car*"
               }
            },
            {  
               "wildcard":{  
                  "results.products.number":"*5*"
               }
            }
         ]
      }
   }
}

What I expect is to get only ID1. Because only it has a product with { "product":"car", "number":"5" } record. But what I get is both ID1 and ID2 because ID2's first record has "product":"car" and third record has "number":"5" records separately.

How can I fix this query?


Solution

  • You need to define your products as a nested type when creating mapping. Try with following mapping example:

    PUT http://localhost:9200/indexname
    
    {
      "mappings": {
         "typename": {
            "properties": {
               "products" : {
                  "type" : "nested"
                }
              }
           }
        }
     }
    

    Then you can use nested queries to match entire elements of your array - just as you need to.

    {
      "query": {
        "nested": {
          "path": "products",
          "query": {
            "bool": {
              "must": [
                { "wildcard": { "products.product": "*car*" }},
                { "wildcard": { "products.number":  "*5*" }} 
              ]
            }
          }
        }
      }
    }