如何在 mongodb 中查询特定月份,而不是日期范围,我需要月份来列出当前月份的客户生日。
在 SQL 中将是这样的:
SELECT * FROM customer WHERE MONTH(bday)='09'
现在我需要在 mongodb 中翻译它。注意:我的日期已经保存在 MongoDate 类型中,我以前使用这种想法很容易工作,但现在我无法轻松找到如何做这个简单的事情。
如何在 mongodb 中查询特定月份,而不是日期范围,我需要月份来列出当前月份的客户生日。
在 SQL 中将是这样的:
SELECT * FROM customer WHERE MONTH(bday)='09'
现在我需要在 mongodb 中翻译它。注意:我的日期已经保存在 MongoDate 类型中,我以前使用这种想法很容易工作,但现在我无法轻松找到如何做这个简单的事情。
使用 MongoDB 3.6 及更高版本,您可以在查询中使用$expr
运算符。find()
这允许您构建查询表达式来比较$match
阶段中同一文档的字段。
db.customer.find({ "$expr": { "$eq": [{ "$month": "$bday" }, 9] } })
对于其他 MongoDB 版本,请考虑运行使用$redact
运算符的聚合管道,因为它允许您与单个管道合并,该功能$project
用于创建表示日期字段的月份的字段并$match
过滤与给定条件匹配的文档月份是九月。
在上面,$redact
使用$cond
三元运算符作为提供条件表达式的手段,该条件表达式将创建进行编辑的系统变量。中的逻辑表达式$cond
将检查日期运算符字段与给定值的相等性,如果匹配,则将$redact
使用系统变量返回文档$$KEEP
,否则使用$$PRUNE
.
运行以下管道应该会给你想要的结果:
db.customer.aggregate([
{ "$match": { "bday": { "$exists": true } } },
{
"$redact": {
"$cond": [
{ "$eq": [{ "$month": "$bday" }, 9] },
"$$KEEP",
"$$PRUNE"
]
}
}
])
这类似于$project
+$match
组合,但您需要选择进入管道的所有其余字段:
db.customer.aggregate([
{ "$match": { "bday": { "$exists": true } } },
{
"$project": {
"month": { "$month": "$bday" },
"bday": 1,
"field1": 1,
"field2": 1,
.....
}
},
{ "$match": { "month": 9 } }
])
使用另一种替代方法,尽管查询速度很慢,但使用以下find()
方法$where
:
db.customer.find({ "$where": "this.bday.getMonth() === 8" })
您可以使用投影运算符来做到这aggregate
一点$month
:
db.customer.aggregate([
{$project: {name: 1, month: {$month: '$bday'}}},
{$match: {month: 9}}
]);
首先,您需要检查数据类型是否在 ISODate 中。如果不是,您可以按照以下示例更改数据类型。
db.collectionName.find().forEach(function(each_object_from_collection){each_object_from_collection.your_date_field=new ISODate(each_object_from_collection.your_date_field);db.collectionName.save(each_object_from_collection);})
现在你可以通过两种方式找到它
db.collectionName.find({ $expr: {
$eq: [{ $year: "$your_date_field" }, 2017]
}});
或者通过聚合
db.collectionName.aggregate([{$project: {field1_you_need_in_result: 1,field12_you_need_in_result: 1,your_year_variable: {$year: '$your_date_field'}, your_month_variable: {$month: '$your_date_field'}}},{$match: {your_year_variable:2017, your_month_variable: 3}}]);
如果您关心效率,您可能希望将月份数据存储在每个文档中的单独字段中。
是的,您可以在这样的日期内获取此结果,
db.collection.find({
$expr: {
$and: [
{
"$eq": [
{
"$month": "$date"
},
3
]
},
{
"$eq": [
{
"$year": "$date"
},
2020
]
}
]
}
})