问题
I am trying to write a query by using the mongo aggregation framework. What I want to achive is to select the orders where ALL shipments have been delivered more than a month ago.
currently I am able to select the orders where AT LEAST ONE shipment has been delivered more than a month ago.
Here's what I have:
db['shop.orders'].aggregate(
{
$match: {
shipments: { $elemMatch: { status: "Delivered", deliveredAt: {"$lte":new Date("2018-07-28")}} }
}
})
How do I have to alter my query to only select the orders where ALL shipments have been delivered more than a month ago?
回答1:
You can use $map to apply your condition for each shipment
and then use $allElementsTrue inside $expr to check if all those elements match:
db.shop_orders.aggregate([
{
$match: { shipments: { $exists: true, $ne: [] } }
},
{
$match: {
$expr: {
$allElementsTrue: {
$map: {
input: "$shipments",
as: "shipment",
in: {
$and: [
{ $eq: [ "$$shipment.status", "Delivered" ] },
{ $lte: [ "$$shipment.deliveredAt", new Date("2018-07-28") ] }
]
}
}
}
}
}
}
])
来源:https://stackoverflow.com/questions/52065224/mongo-query-documents-with-an-array-whose-childs-all-have-to-match-a-query