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

elasticsearch-将嵌套字段与文档中的另一个字段进行比较

慎兴业
2023-03-14

我需要比较同一个文档中的两个字段,其中的实际值无关紧要。考虑这份文件:

_source: {
    id: 123,
    primary_content_type_id: 12,
    content: [
        {
            id: 4,
            content_type_id: 1
            assigned: true
        },
        {
            id: 5,
            content_type_id: 12,
            assigned: false
        }
    ]
}

我需要查找未分配主要内容的所有文档。我无法找到一种方法将primary_content_type_id与嵌套content.content_type_id进行比较,以确保它们具有相同的值。这就是我尝试使用脚本的方法。我不认为我理解脚本,但这可能是解决这个问题的一种方法:

{
    "filter": {
        "nested": {
            "path": "content",
            "filter": {
                "bool": {
                    "must": [
                        {
                            "term": {
                                "content.assigned": false
                            }
                        },
                        {
                            "script": {
                                "script": "primary_content_type_id==content.content_type_id"
                            }
                        }
                    ]
                }
            }
        }
    }
}

请注意,如果我删除过滤器的脚本部分,并将其替换为content_type_id=12的另一个术语过滤器,并在primary_content_id=12。问题是,我不知道primary_content_type_id内容的值是什么(对我的用例也不重要)。content_type_id是。对于content_type_id匹配primary_content_type_id的内容,赋值为false很重要。

使用弹性搜索可以进行此检查吗?

共有1个答案

从元明
2023-03-14

对于嵌套搜索,您正在搜索没有父级的嵌套对象。遗憾的是,没有可用于嵌套对象的隐藏联接。

至少目前,这意味着您不会同时收到脚本中的“父”文档和嵌套文档。您可以通过将脚本替换为这两个脚本并测试结果来确认这一点:

# Parent Document does not exist
"script": {
  "script": "doc['primary_content_type_id'].value == 12"
}

# Nested Document should exist
"script": {
  "script": "doc['content.content_type_id'].value == 12"
}

通过在objects之间循环(而不是让ES用嵌套为您做这件事),您可以以性能较差的方式实现这一点。这意味着您必须将文档和嵌套文档重新索引为单个文档,这样才能工作。考虑到您尝试使用它的方式,这可能不会有太大的不同,甚至可能会表现得更好(特别是考虑到缺乏替代方案)。

# This assumes that your default scripting language is Groovy (default in 1.4)
# Note1: "find" will loop across all of the values, but it will
#  appropriately short circuit if it finds any!
# Note2: It would be preferable to use doc throughout, but since we need the
#  arrays (plural!) to be in the _same_ order, then we need to parse the
#  _source. This inherently means that you must _store_ the _source, which
#  is the default. Parsing the _source only happens on the first touch.
"script": {
  "script": "_source.content.find { it.content_type_id == _source.primary_content_type_id && ! it.assigned } != null",
  "_cache" : true
}

我缓存了结果,因为这里没有发生任何动态变化(例如,没有将日期与< code>now进行比较),所以缓存是非常安全的,从而使将来的查找更快。默认情况下,大多数过滤器都被缓存,但脚本是少数例外。

由于它必须比较两个值以确保找到正确的内部对象,因此您会重复一些工作,但这实际上是不可避免的。拥有术语过滤器很可能比在没有它的情况下进行检查要好。

 类似资料:
  • 我需要比较同一个文档中的两个字段,其中的实际值无关紧要。考虑这份文件: 我需要查找未分配主要内容的所有文档。我无法找到一种方法将primary_content_type_id与嵌套content.content_type_id进行比较,以确保它们具有相同的值。这就是我尝试使用脚本的方法。我不认为我理解脚本,但这可能是解决这个问题的一种方法: 请注意,如果我删除过滤器的脚本部分,并将其替换为的另一个

  • 我有带有实体和嵌套实体的索引。实体由、和嵌套变体组成。实体由、和字段组成。我需要按、和字段聚合搜索结果,以获得每个颜色、大小和价格组的产品数量。如果我对这些字段使用嵌套聚合,我会得到正确的buckes,但是bucket中的文档数是每个bucket的实体数。但是我需要获得每个bucket的实体(根文档)的数量。 例如,第一个产品有变体(红色,小,$10)、(绿色,小,$10)、(红色,中等,$11)

  • 问题内容: 我只想获取嵌套字段,但不能,因为它不是叶字段。 我在下面尝试过,但是无法匹配嵌套对象中的每个ID和名称。 结果: 这是我的预期结果: 问题答案: 如果您没有某个查询应以某种方式匹配嵌套字段,则可以这样进行: 如果您还有一个查询,并且想返回 匹配 的 嵌套文档,则 可以这样操作(使用):

  • 我将Elasticsearch 6与PHP结合使用。 我的文档有一个嵌套字段,如下所示: 基本上每个文档都有很多价格,但我知道每个文档只有一个价格与过滤器/查询匹配。 我用它来搜索和排序,改编自这里的教程:https://www.elastic.co/guide/en/elasticsearch/guide/current/nested-sorting.html(对PHP数组格式表示抱歉): 我得

  • 问题内容: 我正在尝试计算具有唯一嵌套字段值的文档(以及文档本身)。看起来获得唯一文档有效。但是,当我尝试执行的请求时,出现如下错误: 禁止:org.elasticsearch.client.ResponseException:方法[POST],主机 [http:// localhost:9200] ,URI [/ package / _count?ignore_throttled = true&

  • 在这里给ElasticSearch的初学者排名。 我有一个客户列表,他们的订单作为一个嵌套字段。假设文档结构如下: 我想查询的是:在两个日期之间订购了一定数量的用户列表。我希望能够将它与例如生日的范围查询结合起来。 我已经到了这样的地步,我可以使用聚合来获得每个订户在两个日期之间的排序总和: 但是,我想限制查询部分返回的结果,以便更好地与所有其他过滤器混合。 我的第一个想法是使用一个脚本过滤器,并