当前位置: 首页 > 面试题库 >

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

季稳
2023-03-14
问题内容

我需要比较同一文档中的2个字段,实际值无关紧要。考虑以下文档:

_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_idor
的值是什么content.content_type_id。只不过与content_type_id匹配的内容所分配的false无关紧要primary_content_type_id

Elasticsearch是否可以进行此检查?


问题答案:

对于嵌套搜索,您要搜索没有父对象的嵌套对象。不幸的是,没有可以与nested对象一起应用的隐藏联接。

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

# 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使用来为您执行此操作nested)。这意味着您必须将文档和nested文档重新索引为单个文档才能正常工作。考虑到您尝试使用它的方式,这可能并没有太大不同,甚至可能会表现得更好(特别是在缺少替代方法的情况下)。

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

缓存的结果,因为没有动态发生在这里(例如,不比较日期now为实例),所以它是很安全的高速缓存,从而使未来的查找
快。默认情况下,大多数过滤器都是缓存的,但是脚本是少数例外之一。

由于 必须 比较两个值以确保找到正确的内部对象,因此您正在重复 一些
工作,但这实际上是不可避免的。拥有term过滤器最有可能胜过没有过滤器的情况。



 类似资料:
  • 我需要比较同一个文档中的两个字段,其中的实际值无关紧要。考虑这份文件: 我需要查找未分配主要内容的所有文档。我无法找到一种方法将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的初学者排名。 我有一个客户列表,他们的订单作为一个嵌套字段。假设文档结构如下: 我想查询的是:在两个日期之间订购了一定数量的用户列表。我希望能够将它与例如生日的范围查询结合起来。 我已经到了这样的地步,我可以使用聚合来获得每个订户在两个日期之间的排序总和: 但是,我想限制查询部分返回的结果,以便更好地与所有其他过滤器混合。 我的第一个想法是使用一个脚本过滤器,并