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

时间:2016-01-05 14:28:11

标签: mongodb mongodb-query aggregation-framework

我在mongo集合中有出生日期的文件清单。我们有前端,用户可以在数据上添加复杂条件,以获得结果,如

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

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

如果是生日情况,我们必须使用汇总来查询数据库中mongo支持的月份和月份中的日期,这对我的上述用例无效。

有人有建议吗?想法?

3 个答案:

答案 0 :(得分:1)

对于MongoDB 3.6及更高版本,要获取今天过生日的所有用户的列表,请使用 $expr 运算符,该运算符允许在查询语言中使用聚合表达式: / p>

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

对于其他MongoDB版本,您需要运行使用 $redact 管道的聚合操作,以便在 $cond 运算符来执行编辑。考虑执行以下管道:

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

上面的 $cond 表达式

"$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 匹配条件的所有文档(由 {返回的系统变量{3}} 基于 $cond $month $dayOfMonth)并以丢弃文档date operators

答案 1 :(得分:1)

您可以将聚合框架与$dayOfYear运算符一起使用。我假设出生日存储在字段birthday中,并且有一个名为name的字段:

db.data.aggregate(
[
        {
                "$project" : {
                        "_id" : 0,
                        "name" : 1,
                        "birthday" : 1,
                        "score" : 1,
                        "todayDayOfYear" : {
                                "$dayOfYear" : new Date()
                        },
                        "birthDayOfYear" : {
                                "$dayOfYear" : "$birthday"
                        }
                }
        },
        {
                "$project" : {
                        "name" : 1,
                        "birthday" : 1,
                        "score" : 1,
                        "isBirthDay" : {
                                "$eq" : [
                                        "$todayDayOfYear",
                                        "$birthDayOfYear"
                                ]
                        }
                }
        },
        {
                "$match" : {
                        "isBirthDay" : true,
                        "score" : { $gt: 100}
                }
        }
]
)

答案 2 :(得分:0)

Nice solution, taken from here

const User = require('user');
const day = (new Date()).getDate();
const month = (new Date()).getMonth();

const users = await User.find({
    $where:`return this.birthday.getDate() === ${day} && this.birthday.getMonth() === ${month}`
}).exec();