我们说我有一个水果田。我做了一个从3月19日到3月21日的日期范围查询,但想要计算每天不同类型的水果人吃的数量,以及他们每天吃多少次。
这是我到目前为止所拥有的。
db.getCollection('fruits').aggregate([
{
"$match": {
"dates": {
"$gte": new Date(2018, 02, 19, 00, 00, 00),
"$lt": new Date(2018, 02, 21, 00, 00, 00)
}
}
},
{
"$group": {
"_id": {
year: {
$year: "dates"
},
month: {
$month: "dates"
},
day: {
$dayOfMonth: "dates"
},
"fruitField": "$fruits"
},
"count": { "$sum": 1 }
}
}
]

编辑:
预期输出将是这样的: 19日: 橘子:17 苹果:19 梨:8
20: 橘子:6 梨:4
21: 橙子:3 苹果:10 梨:4
答案 0 :(得分:1)
使用MongoDb 3.6及更新版本,您可以利用 $arrayToObject
运算符和 $replaceRoot
管道来获得所需的结果。您需要运行以下聚合管道:
db.getCollection('fruits').aggregate([
{ "$match": {
"dates": {
"$gte": new Date(2018, 02, 19, 00, 00, 00),
"$lt": new Date(2018, 02, 21, 00, 00, 00)
}
} },
{ "$group": {
"_id": {
"fruit": { "$toLower": "$fruits" },
"day": { "$dayOfMonth": "$dates" }
},
"count": { "$sum": 1 }
} },
{ "$group": {
"_id": "$_id.day",
"counts": {
"$push": {
"k": "$_id.fruit",
"v": "$count"
}
}
} },
{ "$replaceRoot": {
"newRoot": {
"$mergeObjects": [
{ "$arrayToObject": "$counts" },
"$$ROOT"
]
}
} },
{ "$project": { "counts": 0 } }
])
对于旧版本,$cond
管道步骤中的$group
运算符可以有效地用于根据fruits
字段值评估计数。您可以按如下方式构建整体聚合管道,以便以所需格式生成结果:
db.getCollection('fruits').aggregate([
{ "$match": {
"dates": {
"$gte": new Date(2018, 02, 19, 00, 00, 00),
"$lt": new Date(2018, 02, 21, 00, 00, 00)
}
} },
{
"$group": {
"_id": { "$dayOfMonth": "$dates" },
"Oranges": {
"$sum": {
"$cond": [ { "$eq": [ "$fruits", "Oranges" ] }, 1, 0 ]
}
},
"Apples": {
"$sum": {
"$cond": [ { "$eq": [ "$fruits", "Apples" ] }, 1, 0 ]
}
},
"Pears": {
"$sum": {
"$cond": [ { "$eq": [ "$fruits", "Pears" ] }, 1, 0 ]
}
}
}
}
])
对于未知和可能的水果值,您可以采用不同的管道:
db.collection('fruits').aggregate([
{ "$match": {
"dates": {
"$gte": new Date(2018, 02, 19, 00, 00, 00),
"$lt": new Date(2018, 02, 21, 00, 00, 00)
}
} },
{ "$group": {
"_id": {
"day": { "$dayOfMonth": "$dates" },
"fruit": { "$toLower": "$fruits" }
},
"count": { "$sum": 1 }
} },
{ "$group": {
"_id": "$_id.day",
"counts": {
"$push": {
"fruit": "$_id.fruit",
"count": "$count"
}
}
} }
])