简体   繁体   中英

ElasticSearch: Multi-level nested query "AND" syntax

I've got an index similar to the example index shown in the elasticsearch doc multi-level nested query example: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-nested-query.html#multi-level-nested-query-ex

Given these example docs:

{
  "driver" : {
        "last_name" : "McQueen",
        "vehicle" : [
            {
                "make" : "Powell Motors",
                "model" : "Canyonero"
            },
            {
                "make" : "Miller-Meteor",
                "model" : "Ecto-1"
            }
        ]
    }
}

{
  "driver" : {
        "last_name" : "Hudson",
        "vehicle" : [
            {
                "make" : "Mifune",
                "model" : "Mach Five"
            },
            {
                "make" : "Miller-Meteor",
                "model" : "Ecto-1"
            }
        ]
    }
}

I need to be able to find documents where the driver.vehicle.make matches two values, ie the driver who has both vehicle makes "Powell Motors" and "Miller-meteor" should match McQueen but not Hudson. I've tried a query similar to the doc example's make and model query, but it returns 0 docs:

{
  "query": {
    "nested": {
      "path": "driver",
      "query": {
        "nested": {
          "path": "driver.vehicle",
          "query": {
            "bool": {
              "must": [
                { "match": { "driver.vehicle.make": "Powell Motors" } },
                { "match": { "driver.vehicle.make": "Miller-Meteor" } }
              ]
            }
          }
        }
      }
    }
  }
}

Changing the "must" to a "should" returns both docs. I can't seem to find a query that will query the vehicle array for multiple value matches in the same doc.

The above query returns 0 documents, as there is no single document (inside driver.vehicle ) in your example that has driver.vehicle.make value as "Powell Motors" and "Miller-meteor".

Note: Here single documents refer to each individual documents (or objects) inside driver.vehicle .

Therefore, when you are changing the must clause to should clause it returns those documents (in this case both the doc), that have driver.vehicle.make value as "Powell Motors" OR "Miller-meteor" . must works as logical AND operator, and should works as logical OR operator.

According to your requirement, I believe you want those documents where driver who has vehicle makes "Powell Motors" OR "Miller-meteor" should match McQueen but not Hudson .

In this case, you need to combine a nested query with a normal query, which can be done using a bool query.

Your modified query will be

{
  "query": {
    "nested": {
      "path": "driver",
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "driver.last_name": "McQueen"
              }
            },
            {
              "nested": {
                "path": "driver.vehicle",
                "query": {
                  "bool": {
                    "should": [
                      {
                        "match": {
                          "driver.vehicle.make": "Powell Motors"
                        }
                      },
                      {
                        "match": {
                          "driver.vehicle.make": "Miller-Meteor"
                        }
                      }
                    ]
                  }
                }
              }
            }
          ]
        }
      }
    }
  }
}

And the search result will be

 "hits" : [
      {
        "_index" : "soidx1",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 3.105637,
        "_source" : {
          "driver" : {
            "last_name" : "McQueen",
            "vehicle" : [
              {
                "make" : "Powell Motors",
                "model" : "Canyonero"
              },
              {
                "make" : "Miller-Meteor",
                "model" : "Ecto-1"
              }
            ]
          }
        }
      }
    ]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM