【问题标题】:Elasticsearch - mutiplication of 2 fields and then sum aggregationElasticsearch - 2个字段的乘法然后汇总聚合
【发布时间】:2017-04-20 00:39:54
【问题描述】:

我正在尝试在 elasticsearch 中进行一个简单的查询,但我不知道该怎么做。我搜遍了整个互联网,没有关于这种情况的讨论。

假设我有类似的物品:

{
  "item_id": 1,
  "item_price": 100,
  "item_quantity": 2
},
{
  "item_id": 2,
  "item_price": 200,
  "item_quantity": 3
},
{
  "item_id": 3,
  "item_price": 150,
  "item_quantity": 1
},
{
  "item_id": 4,
  "item_price": 250,
  "item_quantity": 5
}

我想查询股票的总价。

例如:100*2 + 200*3 + 150*1 + 250*5

这个查询的结果应该是 2200


最后一个数据的答案查询是有效的,但是这个复杂的情况呢:

POST tests/test2/
{
  "item_category": "aaa",
  "items": 
  [
    {
      "item_id": 1,
      "item_price": 100,
      "item_quantity": 2
    },
    {
      "item_id": 2,
      "item_price": 150,
      "item_quantity": 4
    }
  ]
}

POST tests/test2/
{
  "item_category": "bbb",
  "items": 
  [
    {
      "item_id": 3,
      "item_price": 200,
      "item_quantity": 3
    },
    {
      "item_id": 4,
      "item_price": 200,
      "item_quantity": 5
    }
  ]
}

POST tests/test2/
{
  "item_category": "ccc",
  "items": 
  [
    {
      "item_id": 5,
      "item_price": 300,
      "item_quantity": 2
    },
    {
      "item_id": 6,
      "item_price": 150,
      "item_quantity": 8
    }
  ]
}

POST tests/test2/
{
  "item_category": "ddd",
  "items": 
  [
    {
      "item_id": 7,
      "item_price": 80,
      "item_quantity": 10
    },
    {
      "item_id": 8,
      "item_price": 250,
      "item_quantity": 4
    }
  ]
}

在这种情况下,下一个查询不起作用并给我一个错误的答案(1,420 而不是 6,000):

GET tests/test2/_search
{
  "query": {
    "match_all": { }
  },
    "aggs": {
        "total_price": {
            "sum": {
                "script": {
                    "lang": "painless",
                    "inline": "doc['items.item_price'].value * doc['items.item_quantity'].value"
                }
            }
        }
    }
}

【问题讨论】:

    标签: elasticsearch multiplication


    【解决方案1】:

    您可以将sum 聚合用于使用script 计算的值

    {
        "aggs": {
            "total_price": {
                "sum": {
                    "script": {
                        "lang": "painless",
                        "inline": "doc['item_price'].value * doc['item_quantity'].value"
                    }
                }
            }
        }
    }
    

    查看这里https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-sum-aggregation.html#_script_9了解更多详情

    更新

    至于您的高级案例,最好将您的items字段映射为nested类型,之后您可以使用此聚合

    {
        "aggs": {
            "nested": {
                "nested": {
                    "path": "items"
                },
                "aggs": {
                    "total_price": {
                        "sum": {
                            "script": {
                                "inline": "doc['items.item_price'].value * doc['items.item_quantity'].value"
                            }
                        }
                    }
                }
            }
        }
    }
    

    这是问题中示例数据库的映射查询:

    PUT tests
    {
      "mappings": {
        "test2": {
          "properties": {
            "items": {
              "type": "nested" 
            }
          }
        }
      }
    }
    

    澄清一下,您必须在创建索引之前进行映射查询。 (不允许更改现有字段的映射)。

    【讨论】:

    • 太棒了,它适用于这种情况,但我的情况有点复杂,我尝试了相同的算法,但无法得出正确的答案。我正在将我的问题更新为我需要总结的真实情况,请看看我做错了什么。
    • 您好,感谢您的回答,但它给出了一个错误:“[nested] 嵌套路径 [items] 未嵌套”,我试图修复它但没有成功。你知道它是什么吗?
    • 正如我所说,您应该更改映射以使该字段嵌套。看看这里elastic.co/guide/en/elasticsearch/reference/current/nested.html
    • 感谢您的回答,非常有帮助,并给了我需要的答案。请接受您的答案的编辑,这样像我这样的初学者就会理解映射的东西。
    猜你喜欢
    • 2012-08-23
    • 1970-01-01
    • 2016-09-24
    • 2016-11-23
    • 1970-01-01
    • 1970-01-01
    • 2020-02-18
    • 2014-08-24
    • 2014-05-12
    相关资源
    最近更新 更多