(Elasticsearch)如何获取所有文档的嵌套字段的最后一个元素然后执行子聚合

Posted

技术标签:

【中文标题】(Elasticsearch)如何获取所有文档的嵌套字段的最后一个元素然后执行子聚合【英文标题】:(Elasticsearch) How to get the last element of a nested field of all documents then perform sub-aggregations 【发布时间】:2020-03-06 22:05:36 【问题描述】:

我有一个名为 socialmedia 的索引,并尝试使用名为 eng​​strong> 的字段创建查询(省略了一些不必要的字段)

"id" : "1",
"eng": 
[

  "soc_mm_score" : "3",
  "date_updated" : "1520969306",
,

  "soc_mm_score" : "1",
  "date_updated" : "1520972191",
,

  "soc_mm_score" : "4",
  "date_updated" : "1520937222",

]

我有很多来自该索引的文档,其中包含 eng​​strong> 嵌套字段,其中还包含大量“子对象”

现在,我的主要目标是,我应该制定什么 Elasticsearch 查询来过滤掉这些嵌套对象

第 1 步 获取 date_updated 值最高的嵌套对象

第 2 步 获取这些嵌套对象后,执行 sum 聚合,以便我可以为相应的 “最新嵌套对象” 添加 soc_mm_score 字段的所有值

我已经尝试过这个查询,但似乎失败了

ATTEMPT #1(我使用的是 elasticsearch-php API,所以请相信我的查询,它使用这种格式)

'aggs' => [
    'ENG' => [
        'nested' => [
            'path' => 'eng'
        ],
        'aggs' => [
            'FILTER' => [
                'filter' => [
                    'bool' => [
                        'must' => [
                            [
                                // I'm thinking of using max aggregation here
                            ]
                        ]
                    ]
                ]
            ]
            'LATEST' => [
                'top_hits' => [
                    'size' => 1,
                    'sort' => [
                        'eng.date_updated' => [
                            'order' => 'desc'
                        ]
                    ]
                ]
            ]
        ]
    ]
]

PRO/S:返回正确的嵌套对象 CON/S:我无法执行进一步的聚合

样本输出

然后我尝试添加子聚合

然后这是输出

我还有其他方法可以执行此操作吗?

回顾我的理想步骤:

    访问我的 eng​​strong> 嵌套字段 获取该 eng​​strong> 嵌套字段的“最新”/最新元素(由 date_updated 字段值最高的元素指示) 现在,在获取那些“最新”嵌套元素后,为其兄弟嵌套字段进行子聚合,例如:获取 soc_like_countsoc_share_count 的总和eng​​strong> 字段的所有最新元素

【问题讨论】:

你得到答案了吗?请分享。 不幸的是,还没有答案@trusha :( ***.com/questions/51709347/… 到目前为止,我最近的提示是这个链接:***.com/questions/51709347/… 由 Assael 爵士提供,但是,我正在尝试操作嵌套字段,并且“sum_bucket”部分似乎无法读取彼此 我可以标记没有评论的人吗?你好先生@Val 【参考方案1】:

给出一个答案!

"aggs":
        "LATEST": 
            "scripted_metric": 
                "init_script" : """
                  state.te = []; 
                  state.g = 0;
                  state.d = 0;
                  state.a = 0;
                """, 
                "map_script" : """
                  if(state.d != doc['_id'].value)
                      state.d = doc['_id'].value;
                      state.te.add(state.a);
                      state.g = 0;
                      state.a = 0;
                   
                  if(state.g < doc['eng.date_updated'].value) 
                    state.g = doc['eng.date_updated'].value; 
                    state.a = doc['eng.soc_te_score'].value;
                  
                  """,
                "combine_script" : """
                    state.te.add(state.a);
                    double count = 0; 
                    for (t in state.te)  
                      count += t 
                    

                    return count
                  """,
                "reduce_script" : """
                    double count = 0; 
                    for (a in states)  
                      count += a 
                    

                    return count
                """
            
        
      

【讨论】:

只需更改此代码 state.a = doc['eng.soc_te_score'].value; 周围的数组索引以精确定位或确定要汇总的同级嵌套字段,例如:state.a = doc['eng.soc_like_count'].value;

以上是关于(Elasticsearch)如何获取所有文档的嵌套字段的最后一个元素然后执行子聚合的主要内容,如果未能解决你的问题,请参考以下文章

使用 elasticsearchTemplate 从 ElasticSearch 获取所有文档

使用 arrayFilters 更新 MongoDB 中的嵌套子文档

Mongoose - 链接到相同类型的嵌套子文档

Mongoose - 链接到相同类型的嵌套子文档

Elasticsearch:获取 nested 类型数组中的所有元素

Elasticsearch:获取 nested 类型数组中的所有元素