Estoy tratando de concatenar dos matrices anidadas (usando $concatArrays) en un campo nuevo. Me gustaría ordenar la salida de la concatenación (Model.timeline) por una propiedad que existe en ambos conjuntos de objetos. Parece que no puedo hacerlo funcionar con $unwind. Aquí está la consulta sin ninguna clasificación:
Model.aggregate([ { $match: { 'id': id } }, { $project: { id: 1, name: 1, flagged: 1, updatedAt: 1, lastEvent: { $arrayElemAt: ['$events', -1] }, lastimage: { $arrayElemAt: ['$images', -1] }, timeline: { $concatArrays: [ { $filter: { input: '$events', as: 'event', cond: { $and: [ { $gte: ['$$event.timestamp', startAt] }, { $lte: ['$$event.timestamp', endAt] } ]} }}, { $filter: { input: '$images', as: 'image', cond: { $and: [ { $gte: ['$$image.timestamp', startAt] }, { $lte: ['$$image.timestamp', endAt] } ]} }} ] } } } ]);¿Me estoy perdiendo algo obvio?
Necesita tres etapas de canalización después de su partido y proyecto. Primero $unwind , luego $sort y luego re $group . Utilice el operador $first para conservar todos los campos.
{ $undwind : "$timeline", }, { $sort : {"your.sortable.field" : 1} }, { $group : { _id : "$_id", name : {$first : 1}, flagged : {$first : 1}, updatedAt : {$first : 1}, lastEvent : {$first : 1}, lastimage : {$first : 1}, timeline : {$push : "$timeline"} } }Tenga en cuenta que esto funcionará incluso cuando tenga más de un documento después de la fase de coincidencia. Básicamente, esto ordenará los elementos de una matriz dentro de cada documento.
Sus etapas de agregación de $match y $project funcionaron después de que sustituí id con _id y completé los valores para id , startAt y endAt de la siguiente manera:
db.items.aggregate([ { $match: { '_id': '58' } }, { $project: { '_id': 1, name: 1, flagged: 1, updatedAt: 1, lastEvent: { $arrayElemAt: ['$events', -1] }, lastimage: { $arrayElemAt: ['$images', -1] }, timeline: { $concatArrays: [ { $filter: { input: '$events', as: 'event', cond: { $and: [ { $gte: ['$$event.timestamp', ISODate("2016-01-19T20:15:31Z")] }, { $lte: ['$$event.timestamp', ISODate("2016-12-01T20:15:31Z")] } ]} }}, { $filter: { input: '$images', as: 'image', cond: { $and: [ { $gte: ['$$image.timestamp', ISODate("2016-01-19T20:15:31Z")] }, { $lte: ['$$image.timestamp', ISODate("2016-12-01T20:15:31Z")] } ]} }} ] } } } ]);