Mongodb查询特定月份|年份不是日期

时间:2013-09-20 01:29:37

标签: mongodb mongodb-query mongodb-php

如何查询mongodb中的特定月份,而不是日期范围,我需要月份来制作当月的客户生日列表。

在SQL中会是这样的:

SELECT * FROM customer WHERE MONTH(bday)='09'

现在我需要在mongodb中翻译它。 注意:我的日期已经保存在MongoDate类型中,我使用这种思维方式以前很容易工作,但现在我找不到如何做这件简单的事情。

5 个答案:

答案 0 :(得分:14)

使用MongoDB 3.6及更高版本,您可以在 $expr 查询中使用 find() 运算符。这允许您构建查询表达式,以比较 $match 阶段中同一文档的字段。

db.customer.find({ "$expr": { "$eq": [{ "$month": "$bday" }, 9] } })

对于其他MongoDB版本,请考虑运行使用 $redact 运算符的聚合管道,因为它允许您与单个管道合并,具有 {{3}的功能:创建表示日期字段月份的字段,并 $project 过滤文档 符合当月给定条件的九月份。

在上面, $match 使用 $redact tenary运算符作为提供条件表达式的方法,该表达式将创建系统变量新版本。 $cond 中的逻辑表达式将会检查 对于具有给定值的日期运算符字段的相等性,如果匹配则 $cond 将使用 $redact 系统变量返回文档,否则使用 $$KEEP 弃掉。

运行以下管道应该可以获得所需的结果:

db.customer.aggregate([
    { "$match": { "bday": { "$exists": true } } },
    {
        "$redact": {
            "$cond": [
                { "$eq": [{ "$month": "$bday" }, 9] },
                "$$KEEP",
                "$$PRUNE"
            ]
        }
    }
])

这类似于 $$PRUNE + $project 组合,但您需要选择所有其他字段进入管道:

db.customer.aggregate([
    { "$match": { "bday": { "$exists": true } } },
    {
        "$project": {
            "month": { "$month": "$bday" },
            "bday": 1,
            "field1": 1,
            "field2": 1,
            .....
        }
    },
    { "$match": { "month": 9 } }
])

使用 $match 方法,使用 find() 作为另一种替代选择,尽管查询速度慢:

db.customer.find({ "$where": "this.bday.getMonth() === 8" })

答案 1 :(得分:7)

您可以使用aggregate投影操作符{/ 1}}来执行此操作:

db.customer.aggregate([
  {$project: {name: 1, month: {$month: '$bday'}}},
  {$match: {month: 9}}
]);

答案 2 :(得分:2)

如果您担心效率,可能需要将月份数据存储在每个文档的单独字段中。

答案 3 :(得分:0)

首先,您需要检查数据类型是否在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}}]);

答案 4 :(得分:0)

是的,您可以在这样的日期内获取此结果,

db.collection.find({
  $expr: {
          $and: [
              {
                "$eq": [
                  {
                   "$month": "$date"
                 },
                  3
             ]
           },
           {
             "$eq": [
                 {
               "$year": "$date"
                },
                2020
               ]
             }
          ]
         }
        })