mongodb Mongodb查询特定月份|年份不是日期
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18907566/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mongodb query specific month|year not date
提问by Lucas Serafim
How can I query a specific month in mongodb, not date range, I need month to make a list of customer birthday for current month.
如何在 mongodb 中查询特定月份,而不是日期范围,我需要月份来制作当月的客户生日列表。
In SQL will be something like that:
在 SQL 中将是这样的:
SELECT * FROM customer WHERE MONTH(bday)='09'
Now I need to translate that in mongodb. Note: My dates are already saved in MongoDate type, I used this thinking that will be easy to work before but now I can't find easily how to do this simple thing.
现在我需要在 mongodb 中翻译它。注意:我的日期已经保存在 MongoDate 类型中,我以前使用这种想法很容易工作,但现在我无法轻松找到如何做这个简单的事情。
回答by chridam
With MongoDB 3.6 and newer, you can use the $expr
operator in your find()
query. This allows you to build query expressions that compare fields from the same document in a $match
stage.
使用 MongoDB 3.6 和更新版本,您可以$expr
在find()
查询中使用运算符。这允许您构建查询表达式来比较$match
阶段中同一文档中的字段。
db.customer.find({ "$expr": { "$eq": [{ "$month": "$bday" }, 9] } })
For other MongoDB versions, consider running an aggregation pipeline that uses the $redact
operator as it allows you to incorporate with a single pipeline, a functionality with $project
to create a field that represents the month of a date field and $match
to filter the documents
which match the given condition of the month being September.
对于其他 MongoDB 版本,请考虑运行使用$redact
运算符的聚合管道,因为它允许您与单个管道合并,该功能$project
用于创建表示日期字段的月份的字段并$match
过滤与给定条件匹配的文档这个月是九月。
In the above, $redact
uses $cond
tenary operator as means to provide the conditional expression that will create the system variable which does the redaction. The logical expression in $cond
will check
for an equality of a date operator field with a given value, if that matches then $redact
will return the documents using the $$KEEP
system variable and discards otherwise using $$PRUNE
.
在上面,$redact
使用$cond
十元运算符作为提供条件表达式的手段,该条件表达式将创建进行编辑的系统变量。逻辑表达式 in$cond
将检查日期运算符字段与给定值是否相等,如果匹配,则将$redact
使用$$KEEP
系统变量返回文档,否则使用$$PRUNE
.
Running the following pipeline should give you the desired result:
运行以下管道应该会给你想要的结果:
db.customer.aggregate([
{ "$match": { "bday": { "$exists": true } } },
{
"$redact": {
"$cond": [
{ "$eq": [{ "$month": "$bday" }, 9] },
"$$KEEP",
"$$PRUNE"
]
}
}
])
This is similar to a $project
+$match
combo but you'd need to then select all the rest of the fields that go into the pipeline:
这类似于$project
+$match
组合,但您需要然后选择进入管道的所有其余字段:
db.customer.aggregate([
{ "$match": { "bday": { "$exists": true } } },
{
"$project": {
"month": { "$month": "$bday" },
"bday": 1,
"field1": 1,
"field2": 1,
.....
}
},
{ "$match": { "month": 9 } }
])
With another alternative, albeit slow query, using the find()
method with $where
as:
使用另一种替代方法,尽管查询速度很慢,使用find()
方法$where
为:
db.customer.find({ "$where": "this.bday.getMonth() === 8" })
回答by JohnnyHK
回答by tenbatsu
If you're concerned about efficiency, you may want to store the month data in a separate field within each document.
如果您关心效率,您可能希望将月份数据存储在每个文档中的单独字段中。
回答by ABDUL JAMAL
First, you need to check whether the data type is in ISODate. IF not you can change the data type as the following example.
首先,您需要检查数据类型是否在 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);})
Now you can find it in two ways
现在你可以通过两种方式找到它
db.collectionName.find({ $expr: {
$eq: [{ $year: "$your_date_field" }, 2017]
}});
Or by aggregation
或者通过聚合
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}}]);