【问题标题】:Search a nested field for multiple values on the same field with elasticsearch使用 elasticsearch 在嵌套字段中搜索同一字段上的多个值
【发布时间】:2015-07-18 08:39:10
【问题描述】:

我正在尝试查询具有多个值的嵌套属性。

这是一个更清楚的例子。

使用嵌套字段创建索引

    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"}
                  }
                }
              }
            }
        }

    }'

添加一些值

    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"}]
    }'

查询 john 所在的所有类(按预期命中 2 次)

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

查询 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"}}
          ]
        }
      }
    }
  }
}'

我已经尝试过匹配和过滤,但我永远无法让查询返回预期值。

【问题讨论】:

  • 查询只需使用“should”而不是“must”即可。
  • 不,“应该”返回 2 个点击而不是 1 个。
  • 你说得对,我看错了问题。

标签: elasticsearch


【解决方案1】:

它只需要一点改变:

{
  "query": {
    "bool": {
        "must": [
           {
               "nested": {
                  "path":"students",
                  "query": {
                    "bool": {
                      "must": [
                        {"match": {"name": "john"}}
                      ]
                    }
                  }
                }
           },
           {
               "nested": {
                  "path":"students",
                  "query": {
                    "bool": {
                      "must": [
                        {"match": {"name": "jack"}}
                      ]
                    }
                  }
                }
           }
        ]
    }
  }
}

为什么?

基本上,在嵌套查询中,查询和过滤器在单个嵌套文档上共同执行 - 在您的情况下是一个名称。因此,您的查询将选取每个嵌套文档并尝试查找同时具有 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}]
    }'

现在执行以下查询:

{
  "query": {
       "nested": {
          "path":"students",
          "query": {
            "bool": {
              "must": [
                {"match": {"name": "john"}},
                {"match": {"age": 4}}
              ]
            }
          }
        }
  }
}

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

希望对您有所帮助。

【讨论】:

    【解决方案2】:

    您也可以按照以下方式进行。您不需要在嵌套块中再次重复 bool ,因为在该块中只有一个匹配,您可以在没有 bool 的情况下进行术语匹配

    {
      "query": {
        "bool": {
          "must": [{
            "nested": {
              "path": "students",
              "query": {
                {
                  "term": {
                    "name": "john"
                  }
                }
              }
            }
          }, {
            "nested": {
              "path": "students",
              "query": {
                {
                  "term": {
                    "name": "jack"
                  }
                }
              }
            }
          }]
        }
      }
    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多