当前位置: 首页 > 知识库问答 >
问题:

ElasticSearch数组数据使用AND条件匹配嵌套元素中的多个属性

钱震博
2023-03-14

我面临的问题是,我有两个文档,每个文档都包含一个对象数组。我喜欢搜索一个包含嵌套对象两个属性的文档(在同一对象中同时匹配这两个属性),但我总是同时得到这两个文档。

我用以下内容创建了文档:

POST /respondereval/_doc
{
  "resp_id": "1236",
  "responses": [
     {"key": "meta","text":"abc"},
     {"key": "property 1", "text": "yes"},
     {"key": "property 2", "text": "yes"},
  ]
}

POST /respondereval/_doc
{
  "resp_id": "1237",
  "responses": [
     {"key": "meta","text":"abc"},
     {"key": "property 1", "text": "no"},
     {"key": "property 2", "text": "yes"},
  ]
}

我为它们定义了一个索引,以防止ES像这样平整对象:

PUT /respondereval
{
  "mappings" : {
    "properties": {
      "responses" : {
        "type": "nested"
      }
    }
  }
}

现在,我想使用以下查询搜索第一个文档(resp_id 1236):

GET /respondereval/_search
{
  "query": {
    "nested": {
      "path": "responses",
      "query": {
        "bool": {
          "must": [
            { "match": { "responses.key": "property 1" } },
            { "match": { "responses.text": "yes" } }
          ]
        }
      }
    }
  }
}

这应该只返回一个同时匹配两个条件的元素。

不幸的是,它总是返回两个文档。我想这是因为在某个时候,ES仍然会将嵌套对象数组中的值扁平化为这样的内容(简化):

resp_id 1236: "key":["gender", "property 1", "property 2"], "text:["abc", "yes", "yes"]
resp_id 1237: "key":["gender", "property 1", "property 2"], "text:["abc", "no", "yes"]

其中都包含属性1yes

解决这个问题的正确方法是什么,以便只返回包含objects数组中同时匹配两个条件(< code>"key": "property 1 "和" text": "yes")的元素的文档?

共有2个答案

关玮
2023-03-14

有没有直接尝试过没有nested.path的< code>must查询

{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "responses.key": "property 1"
          }
        },
        {
          "match": {
            "responses.text": "yes"
          }
        }
      ]
    }
  }
}
张嘉
2023-03-14

问题在于您的映射。默认情况下,您有使用标准分析器的文本映射。

标准分析器在空白区域创建标记。因此

属性 1 将被标记化为

{
    "tokens": [
        {
            "token": "property",
            "start_offset": 0,
            "end_offset": 8,
            "type": "<ALPHANUM>",
            "position": 0
        },
        {
            "token": "1",
            "start_offset": 9,
            "end_offset": 10,
            "type": "<NUM>",
            "position": 1
        }
    ]
}

同样属性2也是如此。

因此,两份文件都被退回。

当您搜索yes时,它与第二个文档中的第二个文本匹配。属性1匹配属性分析文档中第二个键的标记。

要使其工作:-使用关键字变体

{
  "query": {
    "nested": {
      "path": "responses",
      "query": {
        "bool": {
          "must": [
            { "match": { "responses.key.keyword": "property 1" } },
            { "match": { "responses.text.keyword": "yes" } }
          ]
        }
      }
    }
  }
}

这将是恰当的:

{
  "query": {
    "nested": {
      "path": "responses",
      "query": {
        "bool": {
          "must": [
            { "match_phrase": { "responses.key": "property 1" } },//phrase queries
            { "match": { "responses.text": "yes" } }
          ]
        }
      }
    }
  }
}
 类似资料:
  • 该示例摘自Elasticsearch参考:https://www.elastic.co/guide/en/Elasticsearch/reference/5.3/nested.html 我的索引和这个差不多。唯一的区别是user.first和user.last是关键字类型,所以我可以对它们使用过滤器。 在两种情况下,我应该使用什么查询来获取与上面数组匹配的文档(正好是两个项,一个项是John Sm

  • 我必须在Elasticsearch中构造一个非常重要的查询(现在看来是这样)。假设我有两个实体,每个实体都有一个数组元素,由字符串组成: 数组元素的映射如下(使用动态模板): 实体的Json表示如下: 然后我有了用户输入:['A','B','C']。 我想要实现的是找到只包含输入中指定元素的实体——预期结果是:[A'、[B']、[A'、[C']、[A'],但不是['A'、[E'](因为用户输入中不

  • 我对elasticsearch和spring数据elasticsearch非常陌生,在查询嵌套对象时遇到了一些问题。 我使用ElasticSearch存储库在ElasticSearch中保存一个嵌套模型实例。因此,elasticsearch中只有一个条目包含所有数据,据我所知,这意味着我有一个嵌套文档。 我需要使用Criteria实现一个相对复杂的查询来迭代构建查询。当我尝试使用点表示法访问嵌套属

  • 主要集合是零售商,其中包含用于商店的数组。每个商店都包含一系列优惠(您可以在此商店购买)。这提供了具有数组大小的数组。(见下面的例子) 现在我试图找到所有的优惠,这是在大小。 我尝试了这个查询: 我期待这样的输出: 但是,我的查询的输出还包含与XS、X和M不匹配的offer。 如何强制MongoDB只返回符合我查询的报价? 问候和感谢。

  • 问题内容: 我正在尝试创建仅在数组 的同一项目 上满足多个条件的情况下与文档匹配的查询/过滤器。 假设这是文档: 我希望能够检索在同一元素上具有N个条件匹配的文档。例如:应该匹配文档,但是不应该匹配。 我正在尝试嵌套布尔过滤器(除此过滤器之外,我还有其他过滤器),但是它不起作用,有些类似于 任何想法如何做到这一点?谢谢 编辑 :我更改了映射,现在嵌套查询根据Val的响应工作。我现在无法在嵌套字段上

  • 我有一些数组,如果它们包含类似的值,我想返回这些数组的名称。 我有我的变量,它有多个数组,名字要么是,要么是,要么是。包含的只是变量中某些数组中相同的值。我需要返回数组中包含、和的数组的名称。因此,对于这个示例,我需要返回:。 通过这个函数抛出它们时,我得到一个错误。如何获取返回的数组?