Javascript 按天和项目总数分组,但将项目名称作为关键字输出

Javascript 按天和项目总数分组,但将项目名称作为关键字输出,javascript,mongodb,mongodb-query,aggregation-framework,Javascript,Mongodb,Mongodb Query,Aggregation Framework,我一直在尝试这些例子:和 样本文件: { "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-01-01T08:00:00Z") } { "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-02-03T09:00:00Z") } { "_id" : 3, "item" : "xyz

我一直在尝试这些例子:和

样本文件:

{ "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-01-01T08:00:00Z") }
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-02-03T09:00:00Z") }
{ "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-03T09:05:00Z") }
{ "_id" : 4, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-02-15T08:00:00Z") }
{ "_id" : 5, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T09:05:00Z") }
{ "_id" : 6, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-15T12:05:10Z") }
{ "_id" : 7, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T14:12:12Z") }
但我的需要是它们的混合体。在push示例中,结果如下所示:

{
    "_id" : { "day" : 46, "year" : 2014 },
    "itemsSold" : [
        { "item" : "abc", "quantity" : 10 },
        { "item" : "xyz", "quantity" : 10 },
        { "item" : "xyz", "quantity" : 5 },
        { "item" : "xyz", "quantity" : 10 }
    ]
}
{
    "_id" : { "day" : 34, "year" : 2014 },
    "itemsSold" : [
        { "item" : "jkl", "quantity" : 1 },
        { "item" : "xyz", "quantity" : 5 }
    ]
 }
 {
     "_id" : { "day" : 1, "year" : 2014 },
     "itemsSold" : [ { "item" : "abc", "quantity" : 2 } ]
 }
{ "_id" : { "day" : 46, "year" : 2014 }, "itemsSold" : [ "xyz", "abc" ] }
{ "_id" : { "day" : 34, "year" : 2014 }, "itemsSold" : [ "xyz", "jkl" ] }
{ "_id" : { "day" : 1, "year" : 2014 }, "itemsSold" : [ "abc" ] }
在$addToSet示例中,结果如下所示:

{
    "_id" : { "day" : 46, "year" : 2014 },
    "itemsSold" : [
        { "item" : "abc", "quantity" : 10 },
        { "item" : "xyz", "quantity" : 10 },
        { "item" : "xyz", "quantity" : 5 },
        { "item" : "xyz", "quantity" : 10 }
    ]
}
{
    "_id" : { "day" : 34, "year" : 2014 },
    "itemsSold" : [
        { "item" : "jkl", "quantity" : 1 },
        { "item" : "xyz", "quantity" : 5 }
    ]
 }
 {
     "_id" : { "day" : 1, "year" : 2014 },
     "itemsSold" : [ { "item" : "abc", "quantity" : 2 } ]
 }
{ "_id" : { "day" : 46, "year" : 2014 }, "itemsSold" : [ "xyz", "abc" ] }
{ "_id" : { "day" : 34, "year" : 2014 }, "itemsSold" : [ "xyz", "jkl" ] }
{ "_id" : { "day" : 1, "year" : 2014 }, "itemsSold" : [ "abc" ] }
我想要的是:

{ "_id" : { "day" : 46, "year" : 2014 }, "itemsSold" : { "xyz": 25, "abc": 10 } }
{ "_id" : { "day" : 34, "year" : 2014 }, "itemsSold" : { "xyz": 5, "jkl": 1 ] }
{ "_id" : { "day" : 1, "year" : 2014 }, "itemsSold" : { "abc": 2 } }

这可能吗?如果是的话,任何指导都会很有帮助

根据您的数据,您需要两个阶段,首先收集每个
“项目”
,然后将这些项目详细信息添加到数组中

根据您现有的MongoDB版本,您将如何处理其余部分。对于MongoDB 3.6(从3.4.7开始),您可以使用以下命令重塑数据:

db.collection.aggregate([
  { "$group": {
    "_id": {
      "year": { "$year": "$date" },
      "dayOfYear": { "$dayOfYear": "$date" },
      "item": "$item"
    },
    "total": { "$sum": "$quantity" }
  }},
  { "$group": {
    "_id": {
      "year": "$_id.year",
      "dayOfYear": "$_id.dayOfYear"
    },
    "itemsSold": { "$push": { "k": "$_id.item", "v": "$total" } }
  }},
  { "$sort": { "_id": -1 } },
  { "$addFields": { 
    "itemsSold": { "$arrayToObject": "$itemsSold" }
  }}
])
或者对于早期版本,您可以简单地对结果进行后期处理。无论如何,所有“聚合”工作都是在最后阶段之前完成的:

db.collection.aggregate([
  { "$group": {
    "_id": {
      "year": { "$year": "$date" },
      "dayOfYear": { "$dayOfYear": "$date" },
      "item": "$item"
    },
    "total": { "$sum": "$quantity" }
  }},
  { "$group": {
    "_id": {
      "year": "$_id.year",
      "dayOfYear": "$_id.dayOfYear"
    },
    "itemsSold": { "$push": { "k": "$_id.item", "v": "$total" } }
  }},
  { "$sort": { "_id": -1 } },
  /*
  { "$addFields": { 
    "itemsSold": { "$arrayToObject": "$itemsSold" }
  }}
  */
]).map( d => Object.assign( d, 
  { 
    itemsSold: d.itemsSold.reduce((acc,curr) =>
      Object.assign(acc, { [curr.k]: curr.v }),
      {}
    )
  }
))
任何一种方法都会产生相同的预期结果:

{
        "_id" : {
                "year" : 2014,
                "dayOfYear" : 46
        },
        "itemsSold" : {
                "xyz" : 25,
                "abc" : 10
        }
}
{
        "_id" : {
                "year" : 2014,
                "dayOfYear" : 34
        },
        "itemsSold" : {
                "jkl" : 1,
                "xyz" : 5
        }
}
{
        "_id" : {
                "year" : 2014,
                "dayOfYear" : 1
        },
        "itemsSold" : {
                "abc" : 2
        }
}

因此,您可以使用新的聚合功能进行操作,但实际上最终结果只是“重塑”,这通常最好留给客户端处理。

您所说的“客户端处理”是什么意思?您是否建议我需要以编程方式“重塑”,而不是在mongodb聚合中?如果是,哪个更快?我至少收藏了10万份文件。