使用elasticsearch在同一字段上搜索嵌套字段以查找多个值

Pat*_*até 11 elasticsearch

我正在尝试使用多个值查询嵌套属性.

这是一个更清晰的例子.

使用嵌套字段创建索引

    curl -X DELETE "http://localhost:9200/testing_nested_query/"
    curl -X POST "http://localhost:9200/testing_nested_query/" -d '{
        "mappings": {
            "class": {
              properties: {
                title: {"type": "string"},
                "students": {
                  "type": "nested",
                  "properties": {
                    "name": {"type": "string"}
                  }
                }
              }
            }
        }

    }'
Run Code Online (Sandbox Code Playgroud)

添加一些值

    curl -XPUT 'http://localhost:9200/testing_nested_query/class/1' -d '{
      "title": "class1",
      "students": [{"name": "john"},{"name": "jack"},{"name": "jim"}]
    }'

    curl -XPUT 'http://localhost:9200/testing_nested_query/class/2' -d '{
      "title": "class2",
      "students": [{"name": "john"},{"name": "chris"},{"name": "alex"}]
    }'
Run Code Online (Sandbox Code Playgroud)

查询john所在的所有类(按预期的2次点击)

curl -XGET 'http://localhost:9200/testing_nested_query/class/_search' -d '{
  "query": {
    "nested": {
      "path":"students",
      "query": {
        "bool": {
          "must": [
            {"match": {"students.name": "john"}}
          ]
        }
      }
    }
  }
}'
Run Code Online (Sandbox Code Playgroud)

查询john和jack都参加的类(0结果而不是1)

curl -XGET 'http://localhost:9200/testing_nested_query/class/_search' -d '{
  "query": {
    "nested": {
      "path":"students",
      "query": {
        "bool": {
          "must": [
            {"match": {"students.name": "john"}},
            {"match": {"students.name": "jack"}}
          ]
        }
      }
    }
  }
}'
Run Code Online (Sandbox Code Playgroud)

我已尝试使用匹配和过滤器但我永远无法获得查询以返回预期值.

vai*_*dik 22

它只是需要一点改变:

{
  "query": {
    "bool": {
        "must": [
           {
               "nested": {
                  "path":"students",
                  "query": {
                    "bool": {
                      "must": [
                        {"match": {"name": "john"}}
                      ]
                    }
                  }
                }
           },
           {
               "nested": {
                  "path":"students",
                  "query": {
                    "bool": {
                      "must": [
                        {"match": {"name": "jack"}}
                      ]
                    }
                  }
                }
           }
        ]
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

为什么?

基本上,在嵌套查询中,查询和过滤器在一个嵌套文档上集体执行 - 在您的情况下是一个名称.因此,您的查询将获取每个嵌套文档,并尝试查找具有name相同johnjack同时的每个文档- 这是不可能的.

我的查询尝试查找索引文档,该文档具有一个name等于的john嵌套文档和另一个name等于的嵌套文档jack.所以基本上一个嵌套查询尝试完全匹配一个嵌套文档.

为了证明我的建议,试试这个:

使用与您相同的映射创建相同的索引

**然后索引以下文件**

curl -XPUT 'http://localhost:9200/testing_nested_query/class/1' -d '{
      "title": "class1",
      "students": [{"name": "john", "age": 4},{"name": "jack", "age": 1},{"name": "jim", "age": 9}]
    }'

curl -XPUT 'http://localhost:9200/testing_nested_query/class/2' -d '{
      "title": "class1",
      "students": [{"name": "john", "age": 5},{"name": "jack", "age": 4},{"name": "jim", "age": 9}]
    }'
Run Code Online (Sandbox Code Playgroud)

现在执行以下查询:

{
  "query": {
       "nested": {
          "path":"students",
          "query": {
            "bool": {
              "must": [
                {"match": {"name": "john"}},
                {"match": {"age": 4}}
              ]
            }
          }
        }
  }
}
Run Code Online (Sandbox Code Playgroud)

根据您的期望,这应该匹配2个文档,但它实际上只匹配一个.因为只有一个嵌套文档,它们都name等于johnage等于4.

希望有所帮助.