2

i have a mongodb collection of events from which i want to get the current availablae events so i am using match query like that

   Event.aggregate([ { $match: { isActive: true, ...matchQuery, startDate:{$lt:today}, endDate:{$gt:today} } },])

the problem is that not all the events in my database have startDate and enDate fields and i want to get those events too , so i want to check if startDate and endDate exists then they should be lt and gt than today if they don't exist and the document match the rest of the query , i want to get it . i tried this way but doesn't work

{ $match: { isEnabled: true, ...matchQuery, startDate ? {startDate:{$lt:today}}, endDate ?  endDate:{$gt:today} } },
  

thank you

1

1 Answer 1

7

So the idea is to fetch all documents where:

  1. startDate AND endDate does not exits.

OR

  1. today is between the range startDate AND endDate.

Try this:

let today = new Date();

db.events.aggregate([
    {
        $match: {
            isActive: true,
            $or: [
                {
                    startDate: { $exists: false },
                    endDate: { $exists: false }
                },
                {
                    startDate: { $lt: today },
                    endDate: { $gt: today }
                }
            ]
        }
    }
])

Output:

{
    "_id" : ObjectId("..."),
    "isActive" : true,
    "startDate" : ISODate("2021-03-01T00:00:00.000+05:30"),
    "endDate" : ISODate("2021-03-31T00:00:00.000+05:30")
},
{
    "_id" : ObjectId("..."),
    "isActive" : true
}

Test data:

{
    "_id" : ObjectId("..."),
    "isActive" : true,
    "startDate" : ISODate("2021-03-01T00:00:00.000+05:30"),
    "endDate" : ISODate("2021-03-31T00:00:00.000+05:30")
},
{
    "_id" : ObjectId("..."),
    "isActive" : true,
    "endDate" : ISODate("2021-03-31T00:00:00.000+05:30")
},
{
    "_id" : ObjectId("..."),
    "isActive" : true,
    "startDate" : ISODate("2021-03-01T00:00:00.000+05:30")
},
{
    "_id" : ObjectId("..."),
    "isActive" : true
},
{
    "_id" : ObjectId("..."),
    "isActive" : true,
    "startDate" : ISODate("2021-02-01T00:00:00.000+05:30"),
    "endDate" : ISODate("2021-03-03T00:00:00.000+05:30")
}
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you very much , your answer is logic and it helped me . Thank you
Why your aggregate query not using $expr in $match stage ?
$expr is used to compare fields from the same document in a $match stage. In the above query the comparison is between the fields in a document (startDate, endDate) and external variable (today or a constant value false).

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.