Как использовать агрегат 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)
Другие вопросы по тегам