elasticsearch - 合并多个聚合的结果

标签 elasticsearch elasticsearch-aggregation elasticsearch-query

我有movies索引,其中每个文档都具有以下结构:

文件:

{
                    "color": "Color",
                    "director_name": "Sam Raimi",
                    "actor_2_name": "James Franco",
                    "movie_title": "Spider-Man 2",
                    "actor_3_name" : "Brad Pitt",
                    "actor_1_name": "J.K. Simmons"
}

我需要计算与每个 Actor 对应的电影数量( Actor 可以同时在actor_1_name或actor_2_name或actor_3_name字段中)

这三个字段的映射为:

制图
"mappings": {
            "properties": {
                "actor_1_name": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                },
                "actor_2_name": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                },
                 "actor_3_name": {
                "type": "text",
                "fields": {
                    "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                    }
                }
            }
       }
}

有没有一种方法可以汇总结果,该结果可以合并所有3个actor字段的术语并给出一个整体。

目前,我正在为每个actor字段创建单独的聚合,并通过我的JAVA代码将这些不同的聚合合并为一个。

通过创建不同的聚合来搜索查询:

搜索查询:
{
    "aggs" : {
        "actor1_count" : {
            "terms" : {
                "field" : "actor_1_name.keyword"
            }
        },
        "actor2_count" : {
            "terms" : {
                "field" : "actor_2_name.keyword"
            }
        },
        "actor3_count" : {
            "terms" : {
                "field" : "actor_3_name.keyword"
            }
        }
    }
}

结果

样本结果为:
"aggregations": {
"actor1_count": {

            "buckets": [

                {
                    "key": "Johnny Depp",
                    "doc_count": 2
                }
            ]
},

"actor2_count": {

            "buckets": [
                {
                    "key": "Johnny Depp",
                    "doc_count": 1                   }
      ]
},
"actor3_count": {

            "buckets": [

                {
                    "key": "Johnny Depp",
                    "doc_count": 3
                }

           ]
    }
 }

因此,有可能代替创建不同的聚合,而是可以通过Elasticsearch将所有3个聚合的结果合并在一起。

基本上这是我想要的:
"aggregations": {
    "actor_count": {

                "buckets": [

                    {
                        "key": "Johnny Depp",
                        "doc_count": 6
                    }
                ]
    }
}

(Johnny Depp doc_count应该显示所有3个字段actor_1_name,actor_2_name,actor_3_name的总和,无论存在何处)

我已经尝试过脚本,但是它确实可以正常工作。

脚本查询:
{
    "aggregations": {
        "name": {
            "terms": {
                "script": "doc['actor_1_name.keyword'].value + ' ' +  doc['actor_2_name.keyword'].value + ' ' + doc['actor_2_name.keyword'].value"
            }
        }
    }
}

它是合并 Actor 姓名,然后给出结果。

结果:
"buckets": [

                {
                    "key": "Steve Buscemi Adam Sandler Adam Sandler",
                    "doc_count": 6
                },
                {
                    "key": "Leonard Nimoy Nichelle Nichols Nichelle Nichols",
                    "doc_count": 4
                }

            ]

最佳答案

使用terms不能正常工作。我得求助于scripted_metric,我认为:

GET actors/_search
{
  "size": 0,
  "aggs": {
    "merged_actors": {
      "scripted_metric": {
        "init_script": "state.actors_map=[:]",
        "map_script": """
          def actor_keys = ['actor_1_name', 'actor_2_name', 'actor_3_name'];

          for (def key : actor_keys) {

            def actor_name = doc[key + '.keyword'].value;

            if (state.actors_map.containsKey(actor_name)) {
              state.actors_map[actor_name] += 1;
            } else {
              state.actors_map[actor_name] = 1; 
            }
          }
        """,
        "combine_script": "return state",
        "reduce_script": "return states"
      }
    }
  }
}

屈服
...
"aggregations" : {
    "merged_actors" : {
      "value" : [
        {
          "actors_map" : {
            "Brad Pitt" : 5,
            "J.K. Simmons" : 1,
            "James Franco" : 3
          }
        }
      ]
    }
  }

关于elasticsearch - 合并多个聚合的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61614748/

相关文章:

elasticsearch - Kibana的脚本字段可以在运行时运行吗?

search - 从Elasticsearch中的精确单词匹配开始?

java - 使用 Java 进行 Elasticsearch

python - 计算一个索引中每个字段的所有出现次数

elasticsearch - 在多个字段上聚合-Elasticsearch

elasticsearch - 使用突出显示优化Elasticsearch查询

elasticsearch - 无法在MultiMatch查询中将模糊性设置为自动

elasticsearch - 如何在Elasticsearch中与filter和must_not一起编写至少N个词查询?

elasticsearch - 查询时查询上下文和过滤上下文之间的区别

elasticsearch - 如何使Elasticsearch聚合忽略过滤器,方法与Solr Facets类似