mongodb聚合多个未知的嵌套密钥

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)

Mak*_*dis 8

不幸的是,你想要做的是使用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与聚合计算需要花费数量级的时间.