elasticsearch - 两个聚合的Elasticsearch共同点

标签 elasticsearch aggregation elasticsearch-aggregation elasticsearch-py

我想查找顶级作者和顶级合著者的汇总汇总文档数,它们是索引中源的书目数据字段内的字段。

我目前正在做的是:

1.计算排名前10位的作者的汇总(A,B,C,D .....)。

2.计算排名前十位的合著者(X,Y,Z,...)的汇总。

3.计算交叉对的文档数,例如这些对之间的通用文档数:

[(A,X),(B,Y)....]。 <-----结果

我尝试了子桶聚合,但是它给了我:
[A :(前10个对应于A),B :(前10个对应于B)...]。

最佳答案

好的,因此从上面的评论继续作为答案,使它更易于阅读且不受字符限制。

Comment

I don't think you can use pipeline aggregation to achieve it.

It's not a lot to process on client side i guess. only 20 records (10 for authors and 10 for co-authors) and it would be simple aggregate query.

Another option would be to just get top 10 across both fields and also simple agg query.

But if you really need intersection of both top10s on ES side go with Scripted Metric Aggregation. you can lay your logic in the code



第一个选项很简单:
GET index_name/_search
{
  "size": 0, 
  "aggs": {
    "firstname_dupes": {
      "terms": {
        "field": "authorFullName.keyword",
        "size": 10
      }
    },
    "lastname_dupes": {
      "terms": {
        "field": "coauthorFullName.keyword",
        "size": 10
      }
    }
  }
}

然后在客户端进行结果相交。

第二个如下所示:
GET index_name/_search
{
  "size": 0, 
  "aggs": {
    "name_dupes": {
      "terms": {
        "script": {
          "source": "return [doc['authorFullName.keyword'].value,doc['coauthorFullName.keyword'].value]"
        }
        , "size": 10
      }
    }
  }
}

但这并不是十大作者和十大合著者的交集。这是所有要素的交叉点,然后再进入top10。

第三个选项是编写Scripted Metric Aggregation。没有时间花在算法方面(应该进行优化),但看起来可能是这样。当然,java技能会为您提供帮助。另外,请确保您了解脚本化度量标准聚合执行和性能问题的所有阶段。
GET index_name/_search
{
  "size": 0, 
    "query" : {
        "match_all" : {}
    },
    "aggs": {
        "profit": {
            "scripted_metric": {
                "init_script" : "state.fnames = [:];state.lnames = [:];", 
                "map_script" :
                """
                def key = doc['authorFullName.keyword'];
                def value = '';
                if (key != null && key.value != null) {
                  value = state.fnames[key.value];
                  if(value==null) value = 0;
                  state.fnames[key.value] = value+1
                }
                key = doc['coauthorFullName.keyword'];
                if (key != null && key.value != null) {
                  value = state.lnames[key.value];
                  if(value==null) value = 0;
                  state.lnames[key.value] = value+1
                }
                """,
                "combine_script" : "return state",
                "reduce_script" : 
                """
                def intersection = [];
                def f10_global = new HashSet();
                def l10_global = new HashSet();
                for (state in states) {
                  def f10_local = state.fnames.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByValue())).limit(10).map(e->e.getKey()).collect(Collectors.toList());
                  def l10_local = state.lnames.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByValue())).limit(10).map(e->e.getKey()).collect(Collectors.toList());
                  for(name in f10_local){f10_global.add(name);}
                  for(name in l10_local){l10_global.add(name);}
                }

                for(name in f10_global){
                  if(l10_global.contains(name)) intersection.add(name);
                }
                return intersection;
                """
            }
        }
    }
}

请注意,这里的查询假定您在这些属性上具有keyword。如果不是,只是根据您的情况进行调整。

更新

PS,只是注意到您提到您需要通用计数,而不是通用名称。不知道是什么情况,而是使用map(e->e.getKey())代替map(e->e.getValue().toString())。有关类似问题,请参见the other answer

关于elasticsearch - 两个聚合的Elasticsearch共同点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57169903/

相关文章:

具有最大长度的mysql聚合

elasticsearch - 每天的文档数存储桶并应用了一些过滤器

java - 如何在 Java 中禁用 Elasticsearch RestClient v6.7.0 的 SSL 验证

javascript - 使用工厂函数聚合绑定(bind)中的多个控件

c# - 带C#嵌套客户端的elasticsearch空数组搜索查询

python - PySpark DataFrame 中一行与其前导 3 行之间的差异

elasticsearch - 基于 Elasticsearch 中两个字段的聚合导致 SearchParseExcepetion 为 "cannot find aggregator type"

ElasticSearch 从每个类别中选择一个得分最高的产品

elasticsearch - 使用Elasticsearch进行复合查询

spring-boot - 找不到org.elasticsearch.client.Cancellable的类文件