【发布时间】:2014-04-14 15:38:34
【问题描述】:
使用一个简单但有些人为的例子,假设我在 ElasticSearch 中存储了几个库存文档,其中每个文档代表购买或销售商品:
[
{item_id: "foobar", type: "cost", value: 12.34, timestamp:149382734621},
{item_id: "bizbaz", type: "sale", value: 45.12, timestamp:149383464621},
{item_id: "foobar", type: "sale", value: 32.74, timestamp:149384824621},
{item_id: "foobar", type: "cost", value: 12.34, timestamp:149387435621},
{item_id: "bizbaz", type: "sale", value: 45.12, timestamp:149388434621},
{item_id: "bizbaz", type: "cost", value: 41.23, timestamp:149389424621},
{item_id: "foobar", type: "sale", value: 32.74, timestamp:149389914621},
{item_id: "waahoo", type: "sale", value: 11.23, timestamp:149389914621},
...
]
在指定的时间范围内,我想计算每个项目的当前利润。所以例如我想返回:
foobar_profit = sum(value of all documents item_id="foobar" and type="sale")
-sum(value of all documents item_id="foobar" and type="cost")
bizbaz_profit = sum(value of all documents item_id="bizbaz" and type="sale")
-sum(value of all documents item_id="bizbaz" and type="cost")
...
有两个方面我还不明白如何实现。
-
我知道如何aggregate over terms,所以这将允许我对所有“foobar”项目的值求和,而不管类型如何。 但我不知道如何对两个字段匹配的所有文档求和。例如,我想在复合键
(item_id,type)上聚合上述数据集。然后上面的数据集将产生聚合:- (foobar,cost)->24.68
- (foobar,sale)->65.48
- (商务,成本)->41.23
- (bizbaz,sale)->90.24
- (waahoo,sale)->11.23
-
假设我可以做到 #1,我将拥有像
foobar_cost和foobar_sale这样的聚合。但我不知道如何组合两个聚合,以便在这种情况下foobar_profit = foobar_sale - foobar_cost。所以上面的聚合会变成- foobar_profit->40.8
- bizbaz_profit->49.01
- waahoo_profit->11.23
一些最后的笔记:
- 在上面的示例中,我只列出了 3 个 item_id,但考虑到会有数千个 item_id,所以我不能对每个 item_id 进行特殊情况查询。
- 另外,对于特定商品,
cost和sale商品将在不同的时间出现,因此我们不能将成本和销售价格放在同一个文档中并区分字段。 - 我可以发回所有数据并执行聚合客户端的最后一步,但这可能是大量数据。真的,如果可能的话,我需要在服务器端执行此操作,以便我可以按 profit 对结果进行排序并返回前 N 个。
【问题讨论】:
标签: elasticsearch analytics aggregate