簡體   English   中英

(Elasticsearch)如何獲取所有文檔的嵌套字段的最后一個元素然后執行子聚合

[英](Elasticsearch) How to get the last element of a nested field of all documents then perform sub-aggregations

我有一個名為socialmedia的索引,並嘗試使用這個名為eng的字段創建查詢(省略了一些不必要的字段)

"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嵌套字段,其中還包含很多“子對象”

現在,我的主要目標是,我應該制定什么 Elasticsearch 查詢來過濾掉這些嵌套對象

步驟1
獲取date_updated值最高的嵌套 object

第2步
獲取這些嵌套對象后,執行求和聚合,以便我可以為相應的“最新嵌套對象”添加soc_mm_score字段的所有值

我試過這個查詢,但似乎失敗了

嘗試#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:它返回正確的嵌套 object CON/S:我無法執行進一步的聚合

樣品 Output
輸出 1

然后我嘗試添加子聚合
輸出 2

那么這是output 輸出 3

還有其他方法可以執行此操作嗎?

回顧我的理想步驟:

  1. 訪問我的eng嵌套字段
  2. 獲取該eng嵌套字段的“最新”/最新元素(由具有最高date_updated字段值的元素指示)
  3. 現在,在獲得那些“最近的”嵌套元素之后,對其兄弟嵌套字段進行子聚合,例如:獲取eng字段的所有最新元素的soc_like_countsoc_share_count的總和

制定了答案!

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

度量聚合不支持子聚合, top_hits是一個度量聚合。

一種解決方案是在從 elasticsearch 獲得結果后進行求和。

我創建了一些可能有用的東西,但您必須根據自己的需要對其進行自定義。

假設你的映射

{ 
"my_index": {
    "mappings": {
      "doc": {
        "properties": {
          "eng": {
            "type": "nested",
            "properties": {
              "date_updated": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "soc_like_count": {
                "type": "long"
              },
              "soc_mm_score": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              }
            }
          },
          "id": {
            "type": "keyword"
          }
        }
      }
    }
  }
}

查詢

GET my_index/_search
{
  "size": 0,
  "aggs": {
    "ENG": {
      "nested": {
        "path": "eng"
      },
      "aggs": {
        "sum_soc_top_hits_by_date": {
          "scripted_metric": {
            "init_script": "params._agg.map = new HashMap();params._agg.results = new HashMap();params._agg.size = 1;params._agg.date_arr = null",
            "map_script": "params._agg.map[doc['eng.date_updated.keyword'].value] = doc['eng.soc_like_count'].value;params._agg.date_arr = new ArrayList(params._agg.map.keySet());Collections.sort(params._agg.date_arr, Collections.reverseOrder())",
            "combine_script": "params._agg.size = params._agg.size > params._agg.date_arr.length - 1 ?  params._agg.date_arr.length : params._agg.size;double soc= 0; for (t in params._agg.date_arr.subList(0,params._agg.size)) { params._agg.results[t] = params._agg.map[t];soc += params._agg.map[t]}params._agg.results.total = soc; return params._agg.results",
            "reduce_script": "return params._aggs"
          }
        }
      }
    }
  }
}

更改params._agg.size = 1以更改熱門點擊數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM