【问题标题】:Aggregation by field and then sum value of another field按字段聚合,然后对另一个字段的值求和
【发布时间】:2019-10-25 01:29:09
【问题描述】:

我需要按一个字段聚合,然后在同一个聚合中,用另一个字段值计算总和。但是当执行查询时,第一个聚合是好的,但总和总是 0。

示例索引:


{
    "mappings": {
        "transaction": {
            "dynamic": "strict",
            "properties": {
                "transaction": {
                    "properties": {
                        "amount": {
                            "type": "double"
                        }
                    }
                },
                "infrastructureElement": {
                    "type": "nested",
                    "properties": {
                        "infrastructureElementSubType": {
                            "type": "keyword"
                        }
                    }
                }
            }
        }
    }
}

在下面的查询中,按infrastructureElement.infrastructureElementSubType 聚合,然后将值transactionPurchase.amount 相加到另一个聚合中:

{
    "aggs": {
        "group_by_infrastructure_element": {
            "nested": {
                "path": "infrastructureElement"
            },
            "aggs": {
                "group_by_ie_subtype": {
                    "terms": {
                        "field": "infrastructureElement.infrastructureElementSubType"
                    },
                    "aggs": {
                        "revenue": {
                            "sum": {
                                "field": "transactionPurchase.amount"
                            }
                        }
                    }
                }
            }
        }
    }
}

当前结果:

{
    "took": 6,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
    ...
    },
    "aggregations": {
        "group_by_infrastructure_element": {
            "doc_count": 365,
            "group_by_ie_subtype": {
                "doc_count_error_upper_bound": 0,
                "sum_other_doc_count": 0,
                "buckets": [
                    {
                        "key": "MOBILE",
                        "doc_count": 1,
                        "revenue": {
                            "value": 0
                        }
                    }
                ]
            }
        }
    }
}

提前致谢!

【问题讨论】:

    标签: elasticsearch elasticsearch-aggregation


    【解决方案1】:

    您需要使用Reverse Nested Aggregation,然后链接Sum Aggregation 来计算您要查找的内容:

    聚合查询:

    POST <your_index_name>/_search
    {  
       "size":0,
       "aggs":{  
          "myterms":{  
             "nested":{  
                "path":"infrastructureElement"
             },
             "aggs":{  
                "myterms":{  
                   "terms":{  
                      "field":"infrastructureElement.infrastructureElementSubType",
                      "size":10
                   },
                   "aggs":{  
                      "reverse":{  
                         "reverse_nested":{},
                         "aggs":{  
                            "revenue":{  
                               "sum":{  
                                  "field":"transaction.amount"
                               }
                            }
                         }
                      }
                   }
                }
             }
          }
       }
    }
    

    还要注意映射的结构,transaction 字段不是Nested Type,而是简单的Object Type。现在,如果您在嵌套聚合中,则需要遍历回根,然后执行度量聚合,例如求和以计算amount

    请注意我创建的示例文档的以下响应。

    POST someaggregation/_doc/1
    {
      "transaction":{
        "amount": 100
      },
      "infrastructureElement": [
        {
          "infrastructureElementSubType": "type1"
        },
        {
          "infrastructureElementSubType": "type2"
        }
      ]
    }
    
    POST someaggregation/_doc/2
    {
      "transaction":{
        "amount": 100
      },
      "infrastructureElement": [
        {
          "infrastructureElementSubType": "type1"
        },
        {
          "infrastructureElementSubType": "type2"
        }
      ]
    }
    
    POST someaggregation/_doc/3
    {
      "transaction":{
        "amount": 100
      },
      "infrastructureElement": [
        {
          "infrastructureElementSubType": "type3"
        },
        {
          "infrastructureElementSubType": "type4"
        }
      ]
    }
    

    回应:

    {
      "took" : 519,
      "timed_out" : false,
      "_shards" : {
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 3,
          "relation" : "eq"
        },
        "max_score" : null,
        "hits" : [ ]
      },
      "aggregations" : {
        "myterms" : {
          "doc_count" : 6,
          "myterms" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "type1",
                "doc_count" : 2,
                "reverse" : {
                  "doc_count" : 2,
                  "revenue" : {
                    "value" : 200.0
                  }
                }
              },
              {
                "key" : "type2",
                "doc_count" : 2,
                "reverse" : {
                  "doc_count" : 2,
                  "revenue" : {
                    "value" : 200.0
                  }
                }
              },
              {
                "key" : "type3",
                "doc_count" : 1,
                "reverse" : {
                  "doc_count" : 1,
                  "revenue" : {
                    "value" : 100.0
                  }
                }
              },
              {
                "key" : "type4",
                "doc_count" : 1,
                "reverse" : {
                  "doc_count" : 1,
                  "revenue" : {
                    "value" : 100.0
                  }
                }
              }
            ]
          }
        }
      }
    }
    

    希望这会有所帮助!

    如果您认为这可以解决您的问题,请随时投票和/或接受此答案:)

    【讨论】:

    • 完美的@Kamal,非常感谢它运行良好:) transactionObject Type,因为我的真实索引更复杂。在同一个索引中,我有更多具有更多属性的交易类型对象(即购买、验证...)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-13
    • 2019-01-14
    • 2023-02-11
    相关资源
    最近更新 更多