在日期时间的月,日,年...查询Mongodb

ksc*_*ler 42 python datetime mongodb pymongo mongodb-query

我正在使用mongodb,我以这种方式将datetime存储在我的数据库中

约会"17-11-2011 18:00"我存储:

date = datetime.datetime(2011, 11, 17, 18, 0)
db.mydatabase.mycollection.insert({"date" : date})
Run Code Online (Sandbox Code Playgroud)

我想做这样的请求

month = 11
db.mydatabase.mycollection.find({"date.month" : month})
Run Code Online (Sandbox Code Playgroud)

要么

day = 17
db.mydatabase.mycollection.find({"date.day" : day})
Run Code Online (Sandbox Code Playgroud)

谁知道怎么做这个查询?

DrC*_*sos 49

日期以其时间戳格式存储.如果您想要属于特定月份的所有内容,请查询该月的开始和结束.

var start = new Date(2010, 11, 1);
var end = new Date(2010, 11, 30);

db.posts.find({created_on: {$gte: start, $lt: end}});
//taken from http://cookbook.mongodb.org/patterns/date_range/
Run Code Online (Sandbox Code Playgroud)

  • 哇,这真是太糟糕了......如果你想在特定日期查询,你必须要注意月份和月末......月份可以有28,29,30或31天......为什么他们不能做出类似的事:日期:{$年:2014年,$月:4}?这不是查询语言,而是编程. (7认同)
  • @DrColossos,还有另一种方法可以使用$ where来做到这一点 (2认同)

Ram*_*Vel 29

您无法通过日期或月份等日期组件直接查询mongodb集合.但它可能通过使用特殊的$ where javascript表达式

db.mydatabase.mycollection.find({$where : function() { return this.date.getMonth() == 11} })
Run Code Online (Sandbox Code Playgroud)

或者干脆

db.mydatabase.mycollection.find({$where : 'return this.date.getMonth() == 11'})
Run Code Online (Sandbox Code Playgroud)

(但我更喜欢第一个)

查看以下shell命令以获取日期部分

>date = ISODate("2011-09-25T10:12:34Z")
> date.getYear()
111
> date.getMonth()
8
> date.getdate()
25
Run Code Online (Sandbox Code Playgroud)

编辑:

只有在没有其他选择的情况下才使用$ where.它带来了性能问题.请查看@kamaradclimber和@dcrosta的以下评论.我会让这篇文章公开,以便其他人了解相关事实.

并查看链接$ where查询中的子句和函数以获取更多信息

  • 这是一个方便的想法,但如果你想获得良好的性能,那么真的不鼓励使用$ where:它需要全局锁定.请参阅@DrColossos答案以获得更好的方法. (2认同)
  • 它本身不是一个锁,但是每个`mongod`实例只有一个javascript上下文,可以在其中执行任何javascript(`$ where`,map-reduce作业等).查询将定期生成,因此一个查询不会完全阻止另一个查询,但多个查询或其他javascript工作将会更慢.这就是为什么不推荐`$ where`的原因. (2认同)

Rub*_*ONO 10

如何将月份存储在自己的属性中,因为您需要查询它?不太优雅$where,但可能表现更好,因为它可以被索引.


Ujj*_*jha 8

如果要搜索属于特定月份的文档,请确保查询如下:

// Anything greater than this month and less than the next month
db.posts.find({created_on: {$gte: new Date(2015, 6, 1), $lt: new Date(2015, 7, 1)}});
Run Code Online (Sandbox Code Playgroud)

避免尽可能多地在下面查询.

// This may not find document with date as the last date of the month
db.posts.find({created_on: {$gte: new Date(2015, 6, 1), $lt: new Date(2015, 6, 30)}});

// don't do this too
db.posts.find({created_on: {$gte: new Date(2015, 6, 1), $lte: new Date(2015, 6, 30)}});
Run Code Online (Sandbox Code Playgroud)


chr*_*dam 6

使用$expr允许在查询语言中使用聚合表达式的运算符。这将使您能够在查询中使用日期聚合运算符,如下所示:

month = 11
db.mydatabase.mycollection.find({ 
    "$expr": { 
        "$eq": [ { "$month": "$date" }, month ] 
    } 
})
Run Code Online (Sandbox Code Playgroud)

或者

day = 17
db.mydatabase.mycollection.find({ 
    "$expr": { 
        "$eq": [ { "$dayOfMonth": "$date" }, day ] 
    } 
})
Run Code Online (Sandbox Code Playgroud)

您还可以使用aggregate()接收$redact管道的函数运行聚合操作:

month = 11
db.mydatabase.mycollection.aggregate([
    {
        "$redact": {
            "$cond": [
                { "$eq": [ { "$month": "$date" }, month ] },
                "$$KEEP",
                "$$PRUNE"
            ]
        }
    }
])
Run Code Online (Sandbox Code Playgroud)

对于其他请求

day = 17
db.mydatabase.mycollection.aggregate([
    {
        "$redact": {
            "$cond": [
                { "$eq": [ { "$dayOfMonth": "$date" }, day ] },
                "$$KEEP",
                "$$PRUNE"
            ]
        }
    }
])
Run Code Online (Sandbox Code Playgroud)

使用或

month = 11
day = 17
db.mydatabase.mycollection.aggregate([
    {
        "$redact": {
            "$cond": [
                { 
                    "$or": [ 
                        { "$eq": [ { "$month": "$date" }, month ] },
                        { "$eq": [ { "$dayOfMonth": "$date" }, day ] }
                    ] 
                },
                "$$KEEP",
                "$$PRUNE"
            ]
        }
    }
])
Run Code Online (Sandbox Code Playgroud)

使用 AND

var month = 11,
    day = 17;
db.collection.aggregate([
    {
        "$redact": {
            "$cond": [
                { 
                    "$and": [ 
                        { "$eq": [ { "$month": "$createdAt" }, month ] },
                        { "$eq": [ { "$dayOfMonth": "$createdAt" }, day ] }
                    ] 
                },
                "$$KEEP",
                "$$PRUNE"
            ]
        }
    }
])
Run Code Online (Sandbox Code Playgroud)

$redact运营商合并的功能$project$match管道,将返回所有文档中使用符合条件$$KEEP并丢弃管道那些不使用匹配$$PRUNE变量。


Pun*_*ngh 5

您可以按日期聚合运算符按月、日、年等查找记录,例如$dayOfYear、$dayOfWeek、$month、$year等。

例如,如果您想要 2016 年 4 月创建的所有订单,您可以使用以下查询。

db.getCollection('orders').aggregate(
   [
     {
       $project:
         {
           doc: "$$ROOT",
           year: { $year: "$created" },
           month: { $month: "$created" },
           day: { $dayOfMonth: "$created" }
         }
     },
     { $match : { "month" : 4, "year": 2016 } }
   ]
)
Run Code Online (Sandbox Code Playgroud)

这里创建的是文档中的日期类型字段,我们使用 $$ROOT 将所有其他字段传递给下一阶段的项目,并为我们提供文档的所有详细信息。

您可以根据需要优化上述查询,仅举个例子。要了解有关日期聚合运算符的更多信息,请访问链接