我拥有一个包含create_date属性的文档的集合.我想通过汇总管道发送这些文件,对他们做一些工作.理想情况下,我想在使用$match进行任何其他工作之前使用$match进行过滤,以便我可以利用索引,但是我无法弄清楚如何在我的新的$year / $month / $dayOfMonth操作符中使用$match表达式.
有一些例子浮动了如何在$项目操作中使用运算符,但我担心,通过将$项目作为我的管道中的第一步,我没有访问我的索引(MongoDB文档表明第一个表达式必须是$match以利用索引).
样品数据:
{
post_body: 'This is the body of test post 1',
created_date: ISODate('2012-09-29T05:23:41Z')
comments: 48
}
{
post_body: 'This is the body of test post 2',
created_date: ISODate('2012-09-24T12:34:13Z')
comments: 10
}
{
post_body: 'This is the body of test post 3',
created_date: ISODate('2012-08-16T12:34:13Z')
comments: 10
}
我想通过一个汇总管道运行它,以获得9月份所有帖子的总评论
{
aggregate: 'posts',
pipeline: [
{$match:
/*Can I use the $year/$month operators here to match Sept 2012?
$year:created_date : 2012,
$month:created_date : 9
*/
/*or does this have to be
created_date :
{$gte:{$date:'2012-09-01T04:00:00Z'},
$lt: {$date:'2012-10-01T04:00:00Z'} }
*/
},
{$group:
{_id: '0',
totalComments:{$sum:'$comments'}
}
}
]
}
这是有效的,但匹配失去对更复杂查询的任何索引的访问:
{
aggregate: 'posts',
pipeline: [
{$project:
{
month : {$month:'$created_date'},
year : {$year:'$created_date'}
}
},
{$match:
{
month:9,
year: 2012
}
},
{$group:
{_id: '0',
totalComments:{$sum:'$comments'}
}
}
]
}
如您已经找到的,您不能在文档中不匹配的字段(它的工作方式与查找工作方式完全相同),如果您首先使用$project,那么您将失去使用索引的能力.
您可以做的是将您的努力结合如下:
{
aggregate: 'posts',
pipeline: [
{$match: {
created_date :
{$gte:{$date:'2012-09-01T04:00:00Z'},
$lt: {date:'2012-10-01T04:00:00Z'}
}}
}
},
{$group:
{_id: '0',
totalComments:{$sum:'$comments'}
}
}
]
}
以上只给出了9月的聚合,如果你想聚合多个月,你可以举个例子:
{
aggregate: 'posts',
pipeline: [
{$match: {
created_date :
{ $gte:'2012-07-01T04:00:00Z',
$lt: '2012-10-01T04:00:00Z'
}
},
{$project: {
comments: 1,
new_created: {
"yr" : {"$year" : "$created_date"},
"mo" : {"$month" : "$created_date"}
}
}
},
{$group:
{_id: "$new_created",
totalComments:{$sum:'$comments'}
}
}
]
}
你会得到如下结果:
{
"result" : [
{
"_id" : {
"yr" : 2012,
"mo" : 7
},
"totalComments" : 5
},
{
"_id" : {
"yr" : 2012,
"mo" : 8
},
"totalComments" : 19
},
{
"_id" : {
"yr" : 2012,
"mo" : 9
},
"totalComments" : 21
}
],
"ok" : 1
}