我有一个名为'InventoryPerDay'的文档,其中包含每天商店的库存:
{
_id: "20131202/store_a",
_metadata: {
date: ISODate("2013-12-02T00:00:00Z"),
store: "store_a"
},
inventory: {
quantity: {
item_44: 1350,
item_32: 1,
item_2: 1,
item_9: 1
}
}
},
{
_id: "20131201/store_a",
_metadata: {
date: ISODate("2013-12-01T00:00:00Z"),
store: "store_a"
},
inventory: {
quantity: {
item_44: 1000,
item_32: 5,
item_2: 10
}
}
}
我需要两天内store_a中每件商品的总数量。 “数量”哈希中的项目未知。您可以看到“item_9”存在于2013年12月12日,但不适用于2013年12月1日。
如何使用mongodb中的聚合在多个文档中对未知的嵌套键进行求和?
上述示例的结果应为:
{
store: "store_a",
inventory: {
quantity: {
item_44: 2350,
item_32: 6,
item_2: 11,
item_9: 1
}
}
}
答案 0 :(得分:8)
不幸的是,你想要做的是Mongodb的当前功能(至少没有聚合)是不可能的,如果你保留你当前的架构,你将不得不使用map-reduce来做这个会慢得多
您可以参考here获取解释,说明您的架构不是最优的原因。
您可以参考here了解如何制作架构以及聚合的外观。
如果您可以将字段的名称投影到值,那么您可以使用当前架构进行查询,这样您可以投票选择this ticket,以便获得更多关注。
更新
您需要更改架构
{
_id: "20131202/store_a",
_metadata: {
date: ISODate("2013-12-02T00:00:00Z"),
store: "store_a"
},
inventory: {
quantities: [
{ k : "item_44", v: 1350},
{ k : "item_32", v: 1},
{ k : "item_2", v: 1},
{ k : "item_9", v: 1},
]
}
},
.
.
.
,查询应如下所示
db.InventoryPerDay.aggregate(
[
{
"$unwind" : "$inventory.quantities"
},
{
"$group" : {
"_id" : { "store": "$_metadata.store", "item" : "$inventory.quantities.k"},
"total" : {
"$sum" : "$inventory.quantities.v"
}
}
}
])
这会给你一个像这样的结果
{
result :
[
{ "_id" : { store : "store_a", item : "item_44"}
"total" : 2350
},
{ "_id" : { store : "store_a", item : "item_32"}
"total" : 6
},
{ "_id" : { store : "store_a", item : "item_2"}
"total" : 11
},
{ "_id" : { store : "store_a", item : "item_9"}
"total" : 1
}
]
}
您可以使用汇总管道末尾的$ project运算符格式化这些结果。
关于map-reduce与聚合:Map reduce比聚合慢得多,主要原因是它在一个线程上执行。您可以为this ticket投票,以便他们为多个核心实施它,在大多数情况下,使用map-reduce与聚合计算需要花费数量级的时间。