【问题标题】:Elasticsearch: "must" query on nested fieldsElasticsearch:嵌套字段的“必须”查询
【发布时间】:2020-02-15 16:22:30
【问题描述】:

如何对同一嵌套下的多个字段进行“必须”“匹配”查询?这是一个可重现的 ES 索引,其中“用户”字段被定义为“嵌套”类型。

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

这里有 2 个文件:

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

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

对于此索引,如何查询同时存在“John”和“Alice”的文档?使用上面定义的索引,我希望得到 Document 1 但不是 Document 2。到目前为止,我已经尝试了以下代码,但它没有返回任何命中:

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

【问题讨论】:

  • 你用的是什么版本的elasticsearch?
  • 我使用的是 Elasticsearch 版本 7.4.0

标签: elasticsearch


【解决方案1】:

以下查询是必需的。

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

请注意我是如何在一个 must 子句中使用两个嵌套查询的。那是因为如果您注意到您拥有的文档 alicejohn 都被视为 two different documents

如果您的文档结构如下所示,您的查询将起作用:

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

尝试阅读 this (nested datatype)this (nested query) 链接以了解更多关于它们如何工作的信息,从第二个链接中,您可以看到以下信息:

嵌套查询搜索嵌套字段对象,就像它们已被索引一样 作为单独的文件。

希望有帮助!

【讨论】:

  • 使用这种方法是不可能使用 inner_hits 的,而且仍然不可能使它以这种方式工作。如果您想知道内部命中,我建议以编程方式进行:1)在为每个嵌套子查询构建查询时编写 inner_hits: { i },其中 i - 是子查询的计数。 2) 当您收到结果时,由 [i] 合并 inner_hits
猜你喜欢
  • 2020-09-04
  • 1970-01-01
  • 1970-01-01
  • 2020-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多