Search code examples
elasticsearchelasticsearch-6elasticsearch-query

Query documents that contains all values in nested array Elasticsearch


I'm trying to query documents where the nested array contains all of the elements passed in the query.

The index stores groups and each group has a list of members. I want to query all the groups that contains the given members.

Mapping:

"properties" : {
   "members" : {
      "type" : "nested",
      "properties" : {
         "name" : {
            "type" : "keyword"
         }
       }
    },
    "name" : {
        "type" : "text"
     }
   }
  }
}

Example content:

[
  {
    "name" : "group 1",
    "members" : [
      {
        "name" : "alice"
      },
      {
        "name" : "bob"
      }
    ]
  },
  {
    "name" : "group 2",
    "members" : [
      {
        "name" : "alice"
      },
      {
        "name" : "foo"
      },
      {
        "name" : "bob"
      }
    ]
  },
  {
    "name" : "group 3",
    "members" : [
      {
        "name" : "foo"
      },
      {
        "name" : "bar"
      }
    ]
  }
]

How can I find all groups that have both "alice" and "foo" as members?

I have tried the following query but it returns nothing:

GET /group/_search
{
  "query": {
    "nested": {
      "path": "members",
      "query": {
        "bool": {
          "must": [
            {"match": {"members.name": "alice"}},
            {"match": {"members.name": "foo"}}
          ]
        }
      }
    }
  }
}

I have also tried with term instead of match but it gives no results.


Solution

  • You can use the nested within a must clause. Like this:

    GET /group/_search
    {
     "query": {
       "bool": {
         "must": [
           {
             "nested": {
               "path": "members",
               "query": {
                 "term": {
                   "members.name": {
                     "value": "alice"
                   }
                 }
               }
             }
           },
           {
             "nested": {
               "path": "members",
               "query": {
                 "term": {
                   "members.name": {
                     "value": "foo"
                   }
                 }
               }
             }
           }
         ]
       }
     }
    }