3

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"}}
                    ]
                }
            }
        }
    }
}  
2
  • What version of elasticsearch do you use? Commented Oct 18, 2019 at 17:16
  • I'm using Elasticsearch version 7.4.0 Commented Oct 18, 2019 at 18:12

1 Answer 1

5

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!

Sign up to request clarification or add additional context in comments.

1 Comment

With this approach this is impossible to use inner_hits and this is still not possible to make it work this way. If you want to know inner hits I would recommend doing it programmatically: 1) when building query for each nested sub query write inner_hits: { <provide_name>i }, where i - is a count number of subquery. 2) when you receive results merge inner_hits by <provide_name>[i]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.