Elasticsearch - 两个字段相乘并进行求和聚合

5
我正在尝试在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
这个查询的结果应该是2,200。
上一个数据的答案查询是有效的,但是对于这种复杂情况怎么办呢?
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"
                }
            }
        }
    }
}
1个回答

10

您可以使用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" 
        }
      }
    }
  }
}

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


太好了,这个情况下它能工作,但我的情况有点更复杂,我尝试了相同的算法,但它未能得出正确的答案。我正在更新我的问题以反映我需要求和的真实情况,请看一下看我做错了什么。 - TVC
嗨,谢谢你的回答,但是它给出了一个错误:“[nested] nested path [items] is not nested”,我尝试修复它但没有成功。你有任何想法是什么原因吗? - TVC
就像我之前所说的,你应该更改你的映射,使这个字段成为嵌套的。在这里看一下 https://www.elastic.co/guide/en/elasticsearch/reference/current/nested.html - Random
谢谢你的回答,非常有帮助并且回答了我需要的问题。请接受对你的回答所做的编辑,这样像我这样的初学者就能理解映射的概念。 - TVC

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接