Как использовать агрегат mongodb и получать целые документы
Я серьезно сбит с толку агрегатной функцией mongodb. Все, что я хочу, это найти новейший документ в моей коллекции. Допустим, у каждой записи есть поле "создано"
db.collection.aggregate({
$group: {
_id:0,
'id':{$first:"$_id"},
'max':{$max:"$created"}
}
})
дает правильный результат, но я хочу, чтобы весь документ в результате? Как бы я это сделал?
Это структура документа:
{
"_id" : ObjectId("52310da847cf343c8c000093"),
"created" : 1389073358,
"image" : ObjectId("52cb93dd47cf348786d63af2"),
"images" : [
ObjectId("52cb93dd47cf348786d63af2"),
ObjectId("52f67c8447cf343509d63af2")
],
"organization" : ObjectId("522949d347cf3402c3000001"),
"published" : 1392601521,
"status" : "PUBLISHED",
"tags" : [ ],
"updated" : 1392601521,
"user_id" : ObjectId("52214ce847cf344902000000")
}
6 ответов
В документации я обнаружил, что $$ROOT
выражение решает эту проблему.
Из DOC: http://docs.mongodb.org/manual/reference/operator/aggregation/group/
db.collection.aggregate([
{
$group: {
'_id':"$_id",
'otherFields':{ $push: { fields: $ROOT } }
}
}
])
query = [
{
'$sort': {
'created': -1
}
},
{
$group: {
'_id':null,
'max':{'$first':"$$ROOT"}
}
}
]
db.collection.aggregate(query)
Я думаю, что я понял это. Например, у меня есть коллекция, содержащая массив изображений (или указателей). Теперь я хочу найти документ с наибольшим количеством изображений
results=[];
db.collection.aggregate([
{$unwind: "$images"},
{$group:{_id:"$_id", 'imagecount':{$sum:1}}},
{$group:{_id:"$_id",'max':{$max: "$imagecount"}}},
{$sort:{max:-1}},
{$group:{_id:0,'id':{$first:'$_id'},'max':{$first:"$max"}}}
]).result.forEach(function(d){
results.push(db.stories.findOne({_id:d.id}));
});
Теперь окончательный массив будет содержать документ с наибольшим количеством изображений. Поскольку изображения - это массив, я использую $ unwind, затем я группирую по идентификатору документа и $sum:1, перенаправляю их в $ group, которая находит max, перенаправляем в обратный $ sort для max и $ group из первого результата. Наконец, я извлекаю документ и помещаю его в массив результатов.
db.yourCollection.aggregate([
{
$group: {
_id:"$_id",
root:{ $push: "$$ROOT" }
}
},
{
$unwind: {
path:"$root",
preserveNullAndEmptyArrays: true,
}
},
{
$replaceRoot: {
newRoot: "$root"
}
},
])
Вы должны использовать db.collection.find(), а не db.collection.aggregate():
db.collection.find().sort({"created":-1}).limit(1)