Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get list of users who's birthday is today in MongoDB

I am having the list of documents with date of birth in mongo collection. We are having the front end where user can add the complex conditions on the data to get the result like

(user.dob isToday AND user.score > 1000) OR (user.dob isTomorrow AND user.score > 2000)

Other than date type, I am able to convert the above conditions to corresponding mongo query like {"score" : { $gt: 1000}}.

In case of birthday condition, we have to query the DB with day of the month and month of the year which is supported in mongo only by using aggregate which will not help for my above use case.

Anyone have suggestions? Ideas?

like image 764
bala kumar Avatar asked Oct 27 '25 14:10

bala kumar


1 Answers

For MongoDB 3.6 and greater, to get the list of all users who have a birthday today, use the $expr operator which allows the use of aggregation expressions within the query language:

db.users.find({
   "$expr": { 
       "$and": [
            { "$eq": [ { "$dayOfMonth": "$dob" }, { "$dayOfMonth": new Date() } ] },
            { "$eq": [ { "$month"     : "$dob" }, { "$month"     : new Date() } ] }
       ]
    }
});

For other MongoDB versions, you need to run an aggregate operation that uses a $redact pipeline to filter the documents with the help of $cond operator to do the redaction. Consider executing the following pipeline:

db.users.aggregate([
    {
        "$redact": {
            "$cond": [
                "$and": [
                    { "$eq": [ { "$dayOfMonth": "$dob" }, { "$dayOfMonth": new Date() } ] },
                    { "$eq": [ { "$month"     : "$dob" }, { "$month"     : new Date() } ] }
                ]
            ],
            "$$KEEP",
            "$$PRUNE"
        }
    }
]);

The $cond expression above

"$cond": [
    "$and": [
        { "$eq": [ { "$dayOfMonth": "$dob" }, { "$dayOfMonth": new Date() } ] },
        { "$eq": [ { "$month"     : "$dob" }, { "$month"     : new Date() } ] }
    ]
],

essentially represents the conditional statement

if (dob.getDate() === day && dob.getMonth === month) {
    "$$KEEP" // keep the document in the pipeline
} else {
    "$$PRUNE" // prune/discard the document from the output
}

and the $redact pipeline will return all documents that match the condition with the $$KEEP (a system variable returned by $cond based on the $month and $dayOfMonth date operators) and discards documents otherwise with $$PRUNE.

like image 65
chridam Avatar answered Oct 30 '25 14:10

chridam



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!