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

比较嵌套字段的总和

弘焕
2023-03-14

我正在尝试创建比较和嵌套属性与非嵌套属性的请求

映射:

{
    "mappings": {
        "publishers": {
            "properties": {
                "Accounts": {
                    "type": "nested",
                    "properties": {
                        "FollowersCount": {
                            "type": "long"
                        }
                    }
                },
                "TotalSubscribers": {
                    "type": "long"
                }
            }
        }
    }
}

我要查找sum of Accounts.FollowersCount与TotalSubscribers不相等的文档。

怎么做?

PS:我正在尝试创建这样的内容:

{
    "_source": [
        "TotalSubscribers",
        "Accounts.FollowersCount"
    ],
    "query": {
        "bool": {
            "filter": {
                "script": {
                    "script": {
                        "source": "int total = 0; for (int i = 0; i < doc['Accounts'].length; ++i) {total += doc['Accounts'][i].FollowersCount;} return total == doc['TotalSubscribers'];",
                        "lang": "painless"
                    }
                }
            }
        }
    }
}

但不管用。当我将脚本移动到嵌套块时也会出现同样的问题。那么我就无法访问TotalSubscribers

{
    "query": {
        "term": {
            "PublisherId": 349438
        }
    },
    "script": {
        "source": "ctx._source.TotalSubscribers = ctx._source.Accounts.stream().map(a -> a.FollowersCount).collect(Collectors.summingInt(Integer::intValue));"
    }
}
{
    "error": {
        "root_cause": [
            {
                "type": "script_exception",
                "reason": "runtime error",
                "script_stack": [
                    "java.util.stream.Collectors.lambda$summingInt$11(Collectors.java:467)",
                    "java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)",
                    "java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)",
                    "java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)",
                    "java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)",
                    "java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)",
                    "java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)",
                    "java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)",
                    "java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)",
                    "a -> a.FollowersCount).collect(Collectors.summingInt(Integer::intValue));",
                    "                                                     ^---- HERE"
                ],
                "script": "ctx._source.TotalSubscribers = ctx._source.Accounts.stream().map(a -> a.FollowersCount).collect(Collectors.summingInt(Integer::intValue));",
                "lang": "painless"
            }
        ],
        "type": "script_exception",
        "reason": "runtime error",
        "script_stack": [
            "java.util.stream.Collectors.lambda$summingInt$11(Collectors.java:467)",
            "java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)",
            "java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)",
            "java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)",
            "java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)",
            "java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)",
            "java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)",
            "java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)",
            "java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)",
            "a -> a.FollowersCount).collect(Collectors.summingInt(Integer::intValue));",
            "                                                     ^---- HERE"
        ],
        "script": "ctx._source.TotalSubscribers = ctx._source.Accounts.stream().map(a -> a.FollowersCount).collect(Collectors.summingInt(Integer::intValue));",
        "lang": "painless",
        "caused_by": {
            "type": "null_pointer_exception",
            "reason": null
        }
    },
    "status": 500
}

请求2:

{
    "query": {
        "bool": {
            "must": [
                {
                    "term": {
                        "PublisherId": 349438
                    }
                }
            ]
        }
    },
    "script": {
        "source": "int total = 0; for(int i=0;i<=ctx._source.Accounts.size()-1;i++){total += ctx._source.Accounts[i].FollowersCount} ctx._source['TotalSubscribers'] = total"
    }
}

在“total+=ctx._source.accounts[i].followerscount”附近也有错误

请求3:

{
    "query": {
        "bool": {
            "must": [
                {
                    "term": {
                        "PublisherId": 349438
                    }
                }
            ]
        }
    },
    "script": {
        "source": "int total = 0; for(int i=0;i<=ctx._source.Accounts.size()-1;i++){total += i} ctx._source['TotalSubscribers'] = total"
    }
}

工作正常,在更新totalSubscribers==count帐户项之后。但需要的是账户财产,不是我...

共有1个答案

微生慈
2023-03-14

这可以通过脚本查询来解决,但是由于无法访问脚本查询中的嵌套文档,因此必须以不同的方式进行。在这些情况下,在顶层添加一个新字段总是容易得多,该字段包含followerscount的总和,您可以将其命名为totalfollowerscount

首先,您需要使用_update_by_queryendpoint创建该字段,如下所示:

POST your-index/_update_by_query
{
  "script": {
    "source": """
    ctx._source.TotalFollowersCount = ctx._source.Accounts
      .stream()
      .map(a -> a.FollowersCount ?: 0)
      .collect(Collectors.summingInt(Integer::intValue));
    """
  }
}

然后可以使用脚本查询来查找有问题的文档:

GET your-index/_search
{
  "query": {
    "script": {
      "script": "doc.TotalFollowersCount.value != doc.TotalSubscribers.value"
    }
  }
}
 类似资料:
  • 问题内容: 我需要比较同一文档中的2个字段,实际值无关紧要。考虑以下文档: 我需要找到所有未分配主要内容的文档。我无法找到一种方法来比较primary_content_type_id和嵌套的content.content_type_id以确保它们是相同的值。这是我使用脚本尝试过的。我认为我不了解脚本,但这可能是解决此问题的一种方式: 请注意,如果我删除过滤器的脚本部分,并用另一个术语过滤器替换为,

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

  • 问题内容: 假设我有一个像这样的领域模型: 现在,我可以像这样创建一个教师比较器: 但是,我如何像这样在嵌套字段上比较Lecture? 我无法在模型上添加方法。 问题答案: 您不能嵌套方法引用。您可以改用lambda表达式: 无需反向顺序,它就不再那么冗长了: 注意:在某些情况下,您需要明确声明泛型类型。对于 例如,下面的代码不会没有工作,之前在Java中8。 较新的Java版本具有更好的自动类型

  • 问题内容: 假设我有包含以下字段的文档: 我需要运行一些查询,其中某些条件将需要在两个或多个字段之间进行比较。喜欢 在标准SQL中,一个示例可能是: 我正在阅读一些文档,看起来“脚本”可能是实现此目的的唯一方法?还是还有其他选择? 问题答案: 您可以使用脚本过滤器- 您可以在此处和此处找到更多信息。

  • 我看到一些关于嵌套字段和聚合的帖子,但它们似乎都没有回答我的问题。所以,如果这是一个重复的问题,请原谅,如果有任何帮助,我们将不胜感激。 我们建立了一个讲座索引,讲座具有以下特点: 讲座可以是面对面(现场)或预先录制(在线) 每个讲座可以有多个章节 这些章节中的每一个都可以由不同的讲师讲解(例如:量子物理的第一章可以由五个不同的讲师讲解,其中三个可能是现场直播,另外两个可能在线) 在线讲座每个讲师

  • 本文向大家介绍Javascript的比较汇总,包括了Javascript的比较汇总的使用技巧和注意事项,需要的朋友参考一下 在Javascript应用过程中会遇到各式各样的比较,今天给大家整理了三种情况,一起来学习下。 1.两个对象的比较 Javascript的比较中参杂了一些比较奇怪的特性,我们来看一些比较简单的比较。 由上面的结果可以看出比较两个原始值跟比较对象规则似乎有点不同,比较两个对象值