{ "customerSchemes": [ { "name": "A", "startDate": some date in valid date format }, { "name": "B", "startDate": some date in valid date format. } ] }Estoy tratando de averiguar todos los documentos donde el esquema A comenzó antes que el esquema B. Tenga en cuenta que el esquema Array no está en orden ascendente de startDate. El plan B puede tener una fecha anterior en comparación con el plan A. Creo que el operador de desconexión podría ser útil aquí, pero no estoy seguro de cómo avanzar con los próximos pasos.
Puede usar la matriz $unwind y formatear los elementos para compararlos transformándolos efectivamente en un par de valores clave. Esto supone que solo tiene dos valores de matriz, por lo que no sabía aplicar ningún filtro.
Algo como
db.colname.aggregate( [ {"$unwind":"$customerSchemes"}, {"$group":{ "_id":"$_id", "data":{"$push":"$$ROOT"}, "fields":{ "$mergeObjects":{ "$arrayToObject":[[["$customerSchemes.name","$customerSchemes.startDate"]]] } } }}, {"$match":{"$expr":{"$lt":["$fields.A","$fields.B"]}}}, {"$project":{"_id":0,"data":1}} ])Ejemplo de trabajo aquí: https://mongoplayground.net/p/mSmAXHm0-o-
Usando $reduce
db.colname.aggregate( [ {"$addFields":{ "fields":{ "$reduce":{ "input":"$customerSchemes", "initialValue":{}, "in":{ "$mergeObjects":[ {"$arrayToObject":[[["$$this.name","$$this.startDate"]]]}, "$$value"] } } } }}, {"$match":{"$expr":{"$lt":["$fields.A","$fields.B"]}}}, {"$project":{"fields":0}} ])Ejemplo de trabajo aquí: https://mongoplayground.net/p/WNxbScI9N9b
$filter para filtrar el name: "A" de customerSchemes$arrayElemAt para obtener el primer elemento del resultado filtrado del paso anteriorname: "B"$let declarar variables para "A" en a y "B" en bin verificar la condición de las variables anteriores si la a de startDate de a es mayor que la fecha de inicio de b , luego startDate verdadero, de lo contrario, falso$expr coincide con $eq para que coincida con el proceso anterior, si es cierto, devuelve el documento db.collection.aggregate([ { $match: { $expr: { $eq: [ { $let: { vars: { a: { $arrayElemAt: [ { $filter: { input: "$customerSchemes", cond: { $eq: ["$$this.name", "A"] } } }, 0 ] }, b: { $arrayElemAt: [ { $filter: { input: "$customerSchemes", cond: { $eq: ["$$this.name", "B" ] } } }, 0 ] } }, in: { $gt: ["$$a.startDate", "$$b.startDate"] } } }, true ] } } } ]) También puede usar la condición de expresión de la etapa de coincidencia anterior en la consulta find() sin ninguna canalización de agregación,
sugerencia de soporte más reciente : si está utilizando la versión más reciente (4.4) de MongoDB, puede usar
$firsten lugar de$arrayElemAt, consulte Playground
entonces la idea es
customerSchemes por startDate .customerSchemes.name es A .Prueba esta consulta:
db.collection.aggregate([ { $unwind: "$customerSchemes" }, { $sort: { "customerSchemes.startDate": 1 } }, { $group: { _id: "$_id", customerSchemes: { $push: "$customerSchemes" } } }, { $match: { $expr: { $eq: [{ $first: "$customerSchemes.name" }, "A"] } } } ]);Producción:
/* 1 createdAt:3/12/2021, 6:40:42 PM*/ { "_id" : ObjectId("604b685232a8d433d8ede6c4"), "customerSchemes" : [ { "name" : "A", "startDate" : ISODate("2021-03-01T00:00:00.000+05:30") }, { "name" : "B", "startDate" : ISODate("2021-03-02T00:00:00.000+05:30") } ] }, /* 2 createdAt:3/12/2021, 6:40:42 PM*/ { "_id" : ObjectId("604b685232a8d433d8ede6c6"), "customerSchemes" : [ { "name" : "A", "startDate" : ISODate("2021-03-01T00:00:00.000+05:30") }, { "name" : "B", "startDate" : ISODate("2021-03-05T00:00:00.000+05:30") } ] }Datos de prueba:
/* 1 createdAt:3/12/2021, 6:40:42 PM*/ { "_id" : ObjectId("604b685232a8d433d8ede6c4"), "customerSchemes" : [ { "name" : "A", "startDate" : ISODate("2021-03-01T00:00:00.000+05:30") }, { "name" : "B", "startDate" : ISODate("2021-03-02T00:00:00.000+05:30") } ] }, /* 2 createdAt:3/12/2021, 6:40:42 PM*/ { "_id" : ObjectId("604b685232a8d433d8ede6c5"), "customerSchemes" : [ { "name" : "A", "startDate" : ISODate("2021-03-03T00:00:00.000+05:30") }, { "name" : "B", "startDate" : ISODate("2021-03-02T00:00:00.000+05:30") } ] }, /* 3 createdAt:3/12/2021, 6:40:42 PM*/ { "_id" : ObjectId("604b685232a8d433d8ede6c6"), "customerSchemes" : [ { "name" : "B", "startDate" : ISODate("2021-03-05T00:00:00.000+05:30") }, { "name" : "A", "startDate" : ISODate("2021-03-01T00:00:00.000+05:30") } ] }