Mongo总计$ and在$ match中未返回结果

时间:2018-07-09 15:27:31

标签: mongodb aggregation-framework

我很难弄清楚为什么这个聚合没有返回结果。

我正在尝试查找特定日期的重复项。当我进行查找时,可以看到返回了多个结果:

db.getCollection('transfers').find({createdAt: { $gte: ISODate('2018-07-09') }, dupField:'123456'})

返回4个结果。

但是当我尝试聚合时,它永远不会返回结果。

var g = db.transfers.aggregate([
  { $group: { _id: { dupField: "$dupField" }, count: { $sum: 1 }}},
  { $match: { 
      $and: [
          { "count": { $gt: 1} },
          { "createdAt": { $gte: ISODate('2018-07-09') } }
      ]
  }},
  { $sort: { "count": -1 }}
])
print(g)

当我在createdAt中不使用$match时聚合起作用,但是当我在createdAt中添加$match时聚合不起作用。

我不确定自己在做什么错。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

Mongo的聚合框架由多个阶段组成,每个阶段都会在文档通过管道时对其进行转换。

就您而言,分两个阶段

  1. 管道的第一步是将文档分组。

    { $group: { _id: { dupField: "$dupField" }, count: { $sum: 1 }}}

  2. 然后,您将这些组传递到管道的第二阶段,在此阶段您匹配createdAtcount

但这无法正常工作,因为在第一阶段之后,您的文档将被转换并看上去
像这样

{ _id : 123456, // your dupField count:987 } 在第二阶段,您无权访问createdAt

如果要基于{ "createdAt": { $gte: ISODate('2018-07-09') } }对其进行过滤,请将其移至第一阶段,即在执行管道的$group阶段之前

看起来像这样。

var g = db.transfers.aggregate([

{ $match: { "createdAt": { $gte: ISODate('2018-07-09') } } }, 

{ $group: { _id: { dupField: "$dupField" }, count: { $sum: 1 }}},

{ $match: {  "count": { $gt: 1} } },

{ $sort: { "count": -1 }}
])
print(g)

https://docs.mongodb.com/manual/core/aggregation-pipeline/