我有一个包含该格式文档的MongoDB集合:
{ "_id":..., "Group": 1, "Value": 4 }
{ "_id":..., "Group": 2, "Value": 8 }
{ "_id":..., "Group": 1, "Value": 10 }
依旧......
鉴于X,Y和K,我想使用聚合框架来执行以下操作:
Group
属性的所有文档Group
属性Value
属性关于如何做到这一点的任何想法?
答案 0 :(得分:8)
前两个步骤很简单:
X = 1; Y = 3
db.collection.aggregate( [
{ $match: { Group: { $gte: X, $lt: Y } } },
{ $group: { _id: '$Group' } }
] );
使用上面的数据集,可以得到:
{ "result" : [ { "_id" : 2 }, { "_id" : 1 } ], "ok" : 1 }
为了能够选择具有最大值的K文档,您需要修改您的组以包括每个文档和该组的最大值,然后我们展开以便我们可以对组和值进行排序( DESC):
db.collection.aggregate( [
{ $match: { Group: { $gte: X, $lt: Y } } },
{ $group: {
_id: '$Group',
docs: { $push: { _id: '$_id', Group: '$Group', Value: '$Value' } }
} },
{ $unwind: '$docs' },
{ $sort: { 'docs.Group': 1, 'docs.Value': -1 } }
] );
从现在开始,我们感到非常震惊,因为与普通查询运算符$ push不同,我们无法在聚合框架中执行$ push + $ slice。我们唯一能做的就是另一组,所以你的应用程序可以选出具有最高值的每组K文档:
db.collection.aggregate( [
{ $match: { Group: { $gte: X, $lt: Y } } },
{ $group: {
_id: '$Group',
docs: { $push: { _id: '$_id', Group: '$Group', Value: '$Value' } }
} },
{ $unwind: '$docs' },
{ $sort: { 'docs.Group': 1, 'docs.Value': -1 } }
{ $group: {
_id: '$docs.Group',
docs: { $push: {
_id: '$docs._id',
Group: '$docs.Group',
Value: '$docs.Value'
} }
} }
] );
然后输出(在添加更多文档之后):
{
"result" : [
{
"_id" : 2,
"docs" : [
{
"_id" : ObjectId("51e3a73dea832e98dd545f68"),
"Group" : 2,
"Value" : 22
},
{
"_id" : ObjectId("51e3a738ea832e98dd545f66"),
"Group" : 2,
"Value" : 17
},
{
"_id" : ObjectId("51e3a73aea832e98dd545f67"),
"Group" : 2,
"Value" : 13
},
{
"_id" : ObjectId("51e3a2aaea832e98dd545f64"),
"Group" : 2,
"Value" : 8
},
{
"_id" : ObjectId("51e3a736ea832e98dd545f65"),
"Group" : 2,
"Value" : 7
}
]
},
{
"_id" : 1,
"docs" : [
{
"_id" : ObjectId("51e3a740ea832e98dd545f69"),
"Group" : 1,
"Value" : 21
},
{
"_id" : ObjectId("51e3a2a5ea832e98dd545f63"),
"Group" : 1,
"Value" : 10
},
{
"_id" : ObjectId("51e3a742ea832e98dd545f6a"),
"Group" : 1,
"Value" : 5
},
{
"_id" : ObjectId("51e3a2a3ea832e98dd545f62"),
"Group" : 1,
"Value" : 4
},
{
"_id" : ObjectId("51e3a745ea832e98dd545f6b"),
"Group" : 1,
"Value" : 2
}
]
}
],
"ok" : 1
}
MongoDB的更新> = v3.2:
现在,您可以在聚合管道的末尾添加$project
阶段,以限制每个组的项目数:
$project: {
_id: '$_id',
docs: {
$slice: [
'$docs',
3 // max number of elements returned from the start of the array
]
}
}
答案 1 :(得分:0)
拿N:
db.rec_log.aggregate( [
{ $match: { uid: { $in: [ "zxf-1", "zxf-2" ] } } },
{ $sort: { uid: 1, c_date: -1 } },
{ $group: { _id: '$uid', docs: { $push: { content: '$content' } } } },
{ $project: { _id: '$_id', docs: { $slice: [ '$docs', 2 ] } } }
] );
拿一个:
db.rec_log.aggregate( [
{ $match: { uid: { $in: [ "zxf-1", "zxf-2" ] } } },
{ $sort: { uid: 1, c_date: -1 } },
{ $group: { _id: '$uid', docs: { $push: { content: '$content' } } } },
{ $project: { _id: '$_id', docs0: { $arrayElemAt: ["$docs", 0] } } },
{ $project: { _id: '$_id', latest_content: "$docs0.content" } }
] );