Сортировка вложенного документа с помощью mongoose (MongoDB)

#node.js #mongodb #express #mongoose

#node.js #mongodb #экспресс #mongoose

Вопрос:

Я пытаюсь сделать что-то очень простое, но новое для MongoDB! У меня есть документ под названием Device и вложенный документ под названием Movement. Я хочу получить последние два вложенных документа движения из устройства, упорядоченного по last_seen (дате). Вот что у меня есть вместе с ошибкой, которую я получаю:

 Device.findOne({device_id: "1234"}, {movements: { $sort: {last_seen: -1}, $slice: 2 }}, function(err, device){
     ...
});
  

Ошибка:

MongoError: >1 field in obj: { $sort: { last_seen: -1 }, $slice: 2 }

Комментарии:

1. Пожалуйста, разместите действительные образцы документов.

Ответ №1:

Вы можете использовать aggregate:

 Device.aggregate(
    { $match: { device_id: "1234"}}, // query documents (can return more than one element)
    { $unwind: '$movements'}, //deconstruct the documents
    { $sort: { '$movements.last_seen': -1}},
    { $limit: 2 },
    { $group: { _id: '$device_id', movements: { $push: '$movements }}} //reconstruct the documents
function(err, devices){ 
    //returns an array, probably with one elements depending on `$match` query
});
  

Комментарии:

1. Вот что я получаю из этого: MongoError: спецификация ключа $sort должна быть объектом

2. Также я заметил, что при реконструкции используются только идентификатор и движения. Я хотел бы показать все данные устройства, должен ли я указывать каждую вещь, которую я хочу показать, или есть выбор «все».

3. @gregwinn исправил значение $sort. Что касается реконструкции, вы должны указать каждое поле, которое вы хотите. В вашем случае, когда все поля одинаковы, кроме movements из-за unwind, вы можете включить их в _id like { _id: { device_id: '$device_id', field1: '$field1', ... }, movements: ...} . После этого вы можете использовать проекцию, чтобы удалить вложенность _id, если хотите.