John Jung
John Jung

Reputation: 51

Elasticsearch: "must" query on nested fields

How to do a "must" "match" query on multiple fields under the same nesting? Here's a reproducible ES index where the "user" field is defined as "nested" type.

PUT my_index
{
    "mappings": {
        "properties": {
            "user": {
                "type": "nested",
                "properties": {
                    "firstname": {"type": "text"}
                }
            }
        }
    }
}

And here are 2 documents:

PUT my_index/_doc/1
{
  "user" : [ 
    {
      "firstname" : "John"
    },
    {
      "firstname" : "Alice"
    }
  ]
}

PUT my_index/_doc/2
{
  "user" : [ 
    {
      "firstname" : "Alice"
    }
  ]
}

For this index, how can I query for documents where "John" AND "Alice" both exist? With the index defined above, I expect to get Document 1 but not Document 2. So far, I've tried the following code, but it's returning no hits:

GET my_index/_search 
{
    "query": {
        "nested": {
            "path": "user",
            "query": {
                "bool": {
                    "must": [
                        {"match": {"user.firstname": "John"}},
                        {"match": {"user.firstname": "Alice"}}
                    ]
                }
            }
        }
    }
}  

Upvotes: 3

Views: 6423

Answers (1)

Kamal Kunjapur
Kamal Kunjapur

Reputation: 8840

Below query is what is required.

POST my_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "user",
            "query": {
              "match": {
                "user.firstname": "alice"
              }
            }
          }
        },
        {
          "nested": {
            "path": "user",
            "query": {
              "match": {
                "user.firstname": "john"
              }
            }
          }
        }
      ]
    }
  }
}

Notice how I've made use of two nested queries in a single must clause. That is because if you notice the documents that you have alice and john are both considered two different documents.

The query you have would work if your document structure is something like below:

POST my_index/_doc/3
{
  "user" : [    
    {
      "firstname" : ["Alice", "John"]
    }
  ]
}

Try reading this (nested datatype) and this (nested query) link to understand more on how they work and from the second link, you can see the below info:

The nested query searches nested field objects as if they were indexed as separate documents.

Hope that helps!

Upvotes: 4

Related Questions