3

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

1
  • try like this {"$gte" : ISODate("2021-01-11T00:00:00Z"),} Commented Dec 15, 2021 at 18:42

2 Answers 2

1

$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.

Sign up to request clarification or add additional context in comments.

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.