MongoDB 多键聚合

MongoDB aggregation with multiple keys

我看过一些类似的 questions/answer,例如this one,但我的案子解决不了

我有一个名为 output 的集合,其中包含

形式的文档
{
  "_id" : ObjectId("55e06ac3cd8a52ac141012f2"),
  "Date" : ISODate("2010-11-02T00:00:00Z"),
  "output" : 0,
  "region" : "Gotham"
}

这些文档跨越多个年份和地区,我正在尝试 运行 汇总以获得每个地区每年的总产出明细。如果我忽略年份,我可以使用 this

获得第一部分
output.aggregate(
    [
      { "$group": {
        "_id": { region: "$region"},
        "output": { "$sum": "$output" }
      }}
    ],
    function(err,results) {
      console.log(results);
      db.close();
    }
  );

这给了我

[ { _id: { region: 'Gotham' }, output: 2115715 },
  { _id: { region: 'London' }, output: 6799038 },
  { _id: { region: 'Tokyo' }, output: 8744809 }

但这里的输出是跨年的,我希望它按年细分。

我尝试了以下但它不起作用

output.aggregate(
  [
    {
      $project : {
        year: {
          $year: "$Date"
        }
      }
    },
    {
      "$group": {
        "_id": {
          region: "$region",
          year: ""$year
        },
        "output": { "$sum": "$output" }
      }
    }
  ],
  function(err,results) {
    console.log(results);
    db.close();
  }
);

这导致

[ { _id: { year: 2015 }, output: 0 },
  { _id: { year: 2014 }, output: 0 },
  { _id: { year: 2013 }, output: 0 },
  { _id: { year: 2012 }, output: 0 },
  { _id: { year: 2009 }, output: 0 },
  { _id: { year: 2008 }, output: 0 },
  { _id: { year: 2011 }, output: 0 },
  { _id: { year: 2010 }, output: 0 } ]

核心聚合错误。

当您使用文档中不再存在的像 $project then the only values that come through to the next pipeline stage are only those you specifiy explicitly. So your problem here is you reference fields in $group 这样的管道运算符时,因为您 "omitted them".

所以在 $project 之后你没有提到 "region" 然后该字段不再在文档中要在下一个管道阶段处理,这将导致问题。

基本修正是"include them",但实际上,直接在$group中使用运算符就可以了,因为这样效率更高:

output.aggregate(
  [
    {
      "$group": {
        "_id": {
          "region": "$region",
          "year": { "$year": "$Date" }
        },
        "output": { "$sum": "$output" }
      }
    }
  ],
  function(err,results) {
    console.log(results);
    db.close();
  }
);

完成了

这样想 "unix pipe":

ps aux | grep mongo | grep something

如果您已经过滤掉 "mongo",那么除非您在结果中有 "mongo something",否则不再有 "something" 可以匹配。这就是"pipelines".

的基本原理