Home > Software engineering >  MongoDB Aggregation - query collections that satisfies all array of objects not at least one
MongoDB Aggregation - query collections that satisfies all array of objects not at least one

Time:12-16

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")}}
      ]
  }}
])
  • Related