2015-08-18 3 views
2

У меня возникли проблемы с записью запроса для извлечения последнего объекта массива комментариев, встроенного в документ Story.Как получить последний объект массива во встроенном документе в Mongoose?

Моя коллекция в настоящее время выглядит следующим образом, когда я db.stories.find():

{ 
"_id" : ObjectId("55d3a39565698bbc68079e31"), 
"author" : "Steven Chen", 
"link" : "COCO", 
"title" : "COCO", 
"date" : ISODate("2015-08-18T21:28:53.629Z"), 
"comments" : [ 
    { 
     "author" : "Steven", 
     "text" : "Major", 
     "_id" : ObjectId("55d3a39565698bbc68079e32"), 
     "date" : ISODate("2015-08-18T21:28:53.632Z") 
    }, 
    { 
     "text" : "Canada", 
     "author" : "Steven", 
     "_id" : ObjectId("55d3a39a65698bbc68079e33"), 
     "date" : ISODate("2015-08-18T21:28:58.001Z") 
    }, 
    { 
     "text" : "Usa", 
     "author" : "Steven", 
     "_id" : ObjectId("55d3a39c65698bbc68079e34"), 
     "date" : ISODate("2015-08-18T21:29:00.877Z") 
    } 
], 
"__v" : 0 
} 

Я хочу, чтобы получить последний комментарий по дате, учитывая _id рассказ документа.

Контекст моего кода заключается в том, что есть статья Story со списком комментариев, и я хочу получить последний комментарий и отправить его моему клиенту JS как JSON, используя ajax, чтобы представление можно было обновить с помощью новейшего/последний комментарий.

В этом случае комментарий с «текстом:„Усы“должен быть один получение извлекаться

Может кто-то обеспечить правильный способ сделать это, и это было бы еще лучше, если вы можете объяснить, почему Спасибо.? вы!

ответ

10

ваш «последний» документ всегда будет в конце вашего массива, если не изменить каким-то образом. Добавление элементов в массивах всегда будет идти к «концу» или «добавить» к существующим пунктам при использовании оператора $push или добавлены методы управления массивами в код клиента.

Только такие операторы, как $addToSet или явно используя модификаторы для операции $push, изменят это.

Таким образом, когда в конце массива, что вы, как правило, нужно сделать, это использовать $slice с отрицательным индексом, чтобы получить пункты от «конца» массива:

Model.findById("55d3a39565698bbc68079e31") 
    .select({ "comments": { "$slice": -1 }}) 
    .exec(function(err,doc) { 

    }) 

Если вы на самом деле модифицировали массив, как упоминалось ранее, где последняя дата не является последним элементом массива, тогда вы должны использовать модификатор $sort для обновлений. Как правило, это было бы «неуместно», если вы попросили модификатор $position, или вы использовали $addToSet. $position бы преднамеренным, и вы не можете сортировать, но вы всегда можете отсортировать массив после $addToSet подобной операции, которая размещает Alls даты, чтобы без изменения любого другого содержимого массива:

Model.findByIdAndUpdate("55d3a39565698bbc68079e31", 
    { "$push": { "comments": { "$each": [], "$sort": { "date": 1 } } } } 
) 

С массив, модифицированный той же операцией $slice, применяется к запросам, поскольку массив теперь находится в порядке по дате.

Если же ваше намерение оставить массив в документах из строя, или в другом порядке, вы хотите, но вы также хотите, чтобы получить последнюю дату, то вы можете использовать .aggregate() для $sort и получить запись $last массива :

Model.aggregate(
    [ 
     { "$match": { "_id": ObjectID("55d3a39565698bbc68079e31") } }, 
     { "$unwind": "$comments" }, 
     { "$sort": { "comments.date": 1 } }, 
     { "$group": { 
      "_id": "$_id", 
      "author": { "$first": "$author" }, 
      "link": { "$first": "$link" }, 
      "title": { "$first": "$title" }, 
      "date": { "$first": "$date" }, 
      "comments": { "$last": "$comments" } 
     }} 
    ] 
) 

отмечая, что при использовании рамки агрегации с мангуст, то _id «autocasting», что происходит в других запросах не происходит (это дизайн), поэтому необходимо, чтобы бросить к ObjectId ценности себя, если данные еще не доступны в этой форме и вошли как строка.

Это ваши способы получить последний элемент (необязательно явно отсортированный) из массива.

+0

Спасибо, сэр! Я не знал, что мне нужно использовать $ slice для фильтрации массива. Я ценю ваши дополнительные объяснения по поводу агрегаций и модификаций. Это огромная помощь! –

+0

очень информативный ответ работал как шарм :) –

Смежные вопросы