这是我开始的简化集合:
[{
"_id" : ObjectId("577a598ecab5bb4a002c19da"),
"user" : ObjectId("5775549f9fcaae26c9149026"),
"expense" : 12.87,
"created" : ISODate("2016-07-04T12:43:07.181Z")
},
{
"_id" : ObjectId("577a598ecab5bb4a002c19db"),
"user" : ObjectId("5775549f9fcaae26c9149026"),
"expense" : 12.87,
"created" : ISODate("2016-07-06T12:10:07.181Z")
},
{
"_id" : ObjectId("977a598ecai6bb4a002c19du"),
"user" : ObjectId("6775539f9fciae26c9149027"),
"expense" : 12.87,
"created" : ISODate("2016-07-07T10:43:07.181Z")
},
....
]
我想要group
,并计算created
参数特定日期的所有users
。
我正在尝试这个,但它不工作:
db.getCollection('expenses').group({
keyf: function(doc) {
return {
"day_created": doc.created.getDate(),
"user" : doc.user // or "user" : 1
}
},
cond: {},
reduce: function (value, result) {
result.total++;
},
initial: {
total: 0
}
});
相反,单个组可以完美地工作(对于日期):
db.getCollection('expenses').group({
keyf: function(doc) {
return {
"day_created": doc.created.getDate()
}
},
cond: {},
reduce: function (value, result) {
result.total++;
},
initial: {
total: 0
}
});
<<p> 反应/strong>: [
{
"day_created" : 17,
"total" : 5385
},
{
"day_created" : 18,
"total" : 6338
},
....
]
相反,单独的组可以完美地工作(对于用户):
db.getCollection('tickets').group({
key : {user : 1},
cond: {},
reduce: function (value, result) {
result.total++;
},
initial: {
total: 0
}
});
<<p> 反应/strong>: [
{
"user" : ObjectId("5776f0143543e84a003d53bf"),
"total" : 155
},
{
"user" : ObjectId("577554a89fcaae26c914a8bd"),
"total" : 494
},
...
]
我使用MongoDB shell版本:3.2.1。如何通过使用计算字段而其他字段不使用来进行组聚合?
可以使用聚合框架来获取所需的聚合,而不是使用group函数。考虑运行以下管道:
db.getCollection('expenses').aggregate([
{
"$project": {
"day_created": {
"$dateToString": {
"format": "%Y-%m-%d",
"date": "$created"
}
},
"user": 1
}
},
{
"$group": {
"_id": {
"day_created": "$day_created",
"user": "$user"
},
"total": { "$sum": 1 }
}
},
{
"$project": {
"_id": 0
"user": "$_id.user",
"day_created": "$_id.day_created",
"total": 1
}
}
])
在上面的管道中,第一个 $project
步骤将使用 $dateToString
操作符创建day_created字段。下一个 $group
管道将根据两个键user
和新创建的day_created
字段对文档进行分组,并使用 $sum
计算聚合。
最后一个 $project
管道步骤然后重塑字段以输出所需的JSON结构。
要解决您的问题,您需要将created
日期转换为唯一表示日期的日期格式。
尝试运行以下命令:
db.getCollection('expenses').group({
keyf: function(doc) {
var month = '' + (doc.created.getMonth() + 1),
day = '' + doc.created.getDate(),
year = doc.created.getFullYear();
if (month.length < 2) month = '0' + month;
if (day.length < 2) day = '0' + day;
var day_created = [year, month, day].join('-');
return {
"day_created": day_created,
"user" : doc.user
}
},
cond: {},
reduce: function (value, result) {
result.total++;
},
initial: {
total: 0
}
})