I have collections that have dates in an array like:
datesArray: [{
start_date: Date,
end_date: Date
}]
I want only those collections which satisfy all elements of datesArray.
I am using it in aggregation $match operator like:
Model.aggregate([
{
$match: {
'datesArray.start_date': { $gte: new Date('11-01-21') },
'datesArray.end_date': { $lte: new Date('11-30-21') }
}
}
])
I tried with $elemMatch but it matches at least one array element. I also tried $all with $elemMatch but had no success.
Thank you
CodePudding user response:
$map
your datesArray
to a boolean array by your date range matching criteria. Perform $allElementsTrue
on the result to get your desired result.
inputDate1
and inputDate2
are your inputs. Feel free to update them.
db.collection.aggregate([
{
"$addFields": {
"inputDate1": ISODate("2021-01-01"),
"inputDate2": ISODate("2021-12-31")
}
},
{
"$match": {
$expr: {
"$allElementsTrue": [
{
"$map": {
"input": "$datesArray",
"as": "d",
"in": {
$and: [
{
$gte: [
"$$d.start_date",
"$inputDate1"
]
},
{
$lte: [
"$$d.end_date",
"$inputDate2"
]
}
]
}
}
}
]
}
}
}
])
Here is the Mongo playground for your reference.
CodePudding user response:
You could simply invert each of the critera and use $nor
:
db.collection.aggregate([
{$match: {
$nor: [
{"datesArray.start_date": {$lt: ISODate("2021-11-01")}},
{"datesArray.end_date": {$gt: ISODate("2021-11-30")}}
]
}}
])