Woody
Woody

Reputation: 145

Querying Specific List Indexes In Elastic Search

So I have an search query in Elasticsearch which queries a field called myList. Inside that list are elements. elm1, elm2, and elm3. I want to be able to query that list such that all the elements must match. For example:

myList: [{
   elm1: "value1",
   elm2: "value2",
   elm3: "value4"
   },
   {
   elm1: "value2"
   elm2: "value3"
   elm3: "value3"
   },
   {
   elm1: "value3",
   elm2: "value4",
   elm3: "value5"
   }]

If I construct a query such that it searches for the field: elm1 = value1 and elm2 = value2 and elm3=value3,

"query": {
"bool": {
  "must": [],
  "filter": [
    {
      "bool": {
        "filter": [
          {
            "bool": {
              "should": [
                {
                  "query_string": {
                    "fields": [
                      "myList.elm1.keyword"
                    ],
                    "query": "value1"
                  }
                }
              ],
              "minimum_should_match": 1
            }
          },"bool": {
        "filter": [
          {
            "bool": {
              "should": [
                {
                  "query_string": {
                    "fields": [
                      "myList.elm2.keyword"
                    ],
                    "query": "value2"
                  }
                }
              ],
              "minimum_should_match": 1
            }
          },"bool": {
        "filter": [
          {
            "bool": {
              "should": [
                {
                  "query_string": {
                    "fields": [
                      "myList.elm3.keyword"
                    ],
                    "query": "value3"
                  }
                }
              ],
              "minimum_should_match": 1
            }
          }
         }
        ]
       }
      }

It will return true because

myList[0]['elm1']=value1 
myList[0]['elm2']=value2 
myList[1]['elm3']=value3

This is not what I want.

How do I get it such that

myList[x]['elm1']=value1 
myList[y]['elm2']=value2 
myList[z]['elm3']=value3

Where x=y=z

Upvotes: 0

Views: 48

Answers (2)

Woody
Woody

Reputation: 145

So Joe's answer is nearly there, he's right you need to use the nested field type. His answer gives the possibility of

myList[x]['elm1']=value1 
myList[y]['elm2']=value2 
myList[z]['elm3']=value3

Where x,y,z are independent elements.

If you want x=y=z:

{
  "query": {
    "nested": {
      "path": "myList",
      "query": {
        "bool": {
          "filter": [
            {
              "term": {
                "myList.elm1.keyword": {
                  "value": "value1"
                }
              }
            },
            {
              "term": {
                "myList.elm1.keyword": {
                  "value": "value1"
                }
              }
            },
            {
              "term": {
                "myList.elm1.keyword": {
                  "value": "value1"
                }
              }
            }
          ]
        }
      }
    }
  }
}

Upvotes: 0

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

Reputation: 16925

When you're deailing with arrays of objects, these objects get flattened and essentially lose the connections between each other.

You should use the nested field type instead:

PUT elms_deep
{
  "mappings": {
    "properties": {
      "myList": {
        "type": "nested"
      }
    }
  }
}

then re-add your documents:

POST elms_deep/_doc
{
  "myList": [
    {
      "elm1": "value1",
      "elm2": "value2",
      "elm3": "value4"
    },
    {
      "elm1": "value2",
      "elm2": "value3",
      "elm3": "value3"
    },
    {
      "elm1": "value3",
      "elm2": "value4",
      "elm3": "value5"
    }
  ]
}

and then proceed with the 3 nested term queries -- no need for your original query_string queries when you're targeting .keyword fields:

POST elms_deep/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "nested": {
            "path": "myList",
            "query": {
              "term": {
                "myList.elm1.keyword": {
                  "value": "value1"
                }
              }
            }
          }
        },
        {
          "nested": {
            "path": "myList",
            "query": {
              "term": {
                "myList.elm2.keyword": {
                  "value": "value2"
                }
              }
            }
          }
        },
        {
          "nested": {
            "path": "myList",
            "query": {
              "term": {
                "myList.elm3.keyword": {
                  "value": "value3"
                }
              }
            }
          }
        }
      ]
    }
  }
}

Upvotes: 1

Related Questions