ref*_*los 5 mongodb mongodb-query aggregation-framework
我有一个名为'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
}
}
}
Run Code Online (Sandbox Code Playgroud)
我需要两天内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
}
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,你想要做的是使用Mongodb的当前功能(至少不使用聚合)是不可能的,如果你保留当前的模式,你将不得不使用map-reduce来做这个会慢得多.
您可以在这里参考解释,为什么您的架构不是最优的.
您可以在这里参考以了解如何制作架构以及聚合应该如何.
如果您可以将字段的名称投影到值,那么您对当前架构的要求也是可能的,因此您可以投票支持此票据,以便获得更多关注.
更新
您需要更改架构
{
_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},
]
}
},
.
.
.
Run Code Online (Sandbox Code Playgroud)
并且查询应该如下所示
db.InventoryPerDay.aggregate(
[
{
"$unwind" : "$inventory.quantities"
},
{
"$group" : {
"_id" : { "store": "$_metadata.store", "item" : "$inventory.quantities.k"},
"total" : {
"$sum" : "$inventory.quantities.v"
}
}
}
])
Run Code Online (Sandbox Code Playgroud)
这会给你一个像这样的结果
{
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
}
]
}
Run Code Online (Sandbox Code Playgroud)
您可以使用聚合管道末尾的$ project运算符格式化这些结果.
关于map-reduce与聚合:Map reduce比聚合慢得多,主要原因是它在一个线程上执行.您可以为此票证投票,以便为多个核心实施该票证,在大多数情况下,使用map-reduce与聚合计算需要花费数量级的时间.