Elasticsearch: search/query for multiple strings within same depth of json

Viewed 74

Is it possible to query elasticsearch such that it follows two queries?

For example, if I have the following,

[{
      "items": [
            { 
                "color" : "blue",
                "shape" : "circle",
            },{ 
                "color" : "yellow",
                "shape" : "square",
            },{ 
                "color" : "yellow",
                "shape" : "square",
            }                           
},{
      "items": [
            { 
                "color" : "blue",
                "shape" : "triangle",
            },{ 
                "color" : "pink",
                "shape" : "circle",
            },{ 
                "color" : "red",
                "shape" : "circle",
            }                   
},{
      "items": [
{ 
                "color" : "red",
                "shape" : "rectangle",
            },{ 
                "color" : "blue",
                "shape" : "circle",
            },{ 
                "color" : "purple",
                "shape" : "oval",
            }                   
}]

and I want to search for items only with color (blue) AND shape (circle). Only the first and third should be returned. Therefore, the response should be

[{
      "items": [
            { 
                "color" : "blue",
                "shape" : "circle",
            },{ 
                "color" : "yellow",
                "shape" : "square",
            },{ 
                "color" : "yellow",
                "shape" : "square",
            }                           
},
{
      "items": [
            { 
                "color" : "red",
                "shape" : "rectangle",
            },{ 
                "color" : "blue",
                "shape" : "circle",
            },{ 
                "color" : "purple",
                "shape" : "oval",
            }                   
}]

However, currently if I use the call below, all entries would be returned since they all have color:blue and shape:circle.

{
    "query": {
        "query_string": {
            "query": "color:blue AND shape:circle"
        }
    }
}

(but I need both to be contained together as one item)... Is this possible with Elasticsearch?

1 Answers

Since you want to query on each object separately, it is better to use nested data type instead of object data type.

Adding a working example with index mapping, search query and search result

Index Mapping:

{
  "mappings": {
    "properties": {
      "items": {
        "type": "nested"
      }
    }
  }
}

Search Query:

{
  "query": {
    "nested": {
      "path": "items",
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "items.color": "blue"
              }
            },
            {
              "match": {
                "items.shape": "circle"
              }
            }
          ]
        }
      }
    }
  }
}

Search Result:

"hits": [
      {
        "_index": "68853344",
        "_type": "_doc",
        "_id": "1",
        "_score": 1.8483298,
        "_source": {
          "items": [
            {
              "color": "blue",
              "shape": "circle"
            },
            {
              "color": "yellow",
              "shape": "square"
            },
            {
              "color": "yellow",
              "shape": "square"
            }
          ]
        }
      },
      {
        "_index": "68853344",
        "_type": "_doc",
        "_id": "3",
        "_score": 1.8483298,
        "_source": {
          "items": [
            {
              "color": "red",
              "shape": "rectangle"
            },
            {
              "color": "blue",
              "shape": "circle"
            },
            {
              "color": "purple",
              "shape": "oval"
            }
          ]
        }
      }
    ]
Related