如何在MongoDB中获取今天是生日的用户列表

问题描述:

我在mongo馆藏中有出生日期的文件清单.我们拥有前端,用户可以在其上向数据添加复杂条件以获得类似

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)

除日期类型外,我还可以将上述条件转换为相应的mongo查询,例如{"score" : { $gt: 1000}}.

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

在发生生日的情况下,我们只能使用mongo来查询数据库,并使用mongo支持的月份和年份中的月份.

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.

有人有建议吗?想法?

对于MongoDB 3.6及更高版本,要获取今天有生日的所有用户的列表,请使用

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() } ] }
       ]
    }
});


对于其他MongoDB版本,您需要运行使用 $cond 运算符进行修改.考虑执行以下管道:


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


$cond 上方的表达式


The $cond expression above

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

本质上代表条件语句

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

$redact 管道将返回所有符合条件且符合 $$KEEP ( $month 日期运算符)和光盘否则使用 $$PRUNE .

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.