我正在使用mongodb并以这种方式将datetime存储在我的数据库中
日期“17-11-2011 18:00”我存储:
date = datetime.datetime(2011, 11, 17, 18, 0)
db.mydatabase.mycollection.insert({"date" : date})
我想做这样的请求
month = 11
db.mydatabase.mycollection.find({"date.month" : month})
或
day = 17
db.mydatabase.mycollection.find({"date.day" : day})
任何人都知道如何进行此查询?
答案 0 :(得分:47)
日期以其时间戳格式存储。如果您想要属于特定月份的所有内容,请查询该月的开始和结束。
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/
答案 1 :(得分:28)
您无法通过日期或月份等日期组件直接查询mongodb集合。但是可以使用特殊的 $ where javascript表达式
db.mydatabase.mycollection.find({$where : function() { return this.date.getMonth() == 11} })
或只是
db.mydatabase.mycollection.find({$where : 'return this.date.getMonth() == 11'})
(但我更喜欢第一个)
查看以下shell命令以获取日期部分
>date = ISODate("2011-09-25T10:12:34Z")
> date.getYear()
111
> date.getMonth()
8
> date.getdate()
25
修改强>
只有在没有其他选择的情况下才使用$ where。它带来了性能问题。请查看@kamaradclimber和@dcrosta的以下评论。我会让这篇文章公开,以便其他人了解相关事实。
答案 2 :(得分:10)
如何将月份存储在自己的属性中,因为您需要查询它?不如$where
优雅,但可能会更好,因为它可以被索引。
答案 3 :(得分: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)}});
尽可能避免像下面那样查询。
// 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)}});
答案 4 :(得分:3)
您可以使用 aggregate()
函数运行汇总操作,该函数接收使用$redact
的 Date Aggregation Operators 管道条件表达式:
var month = 11;
db.collection.aggregate([
{
"$redact": {
"$cond": [
{ "$eq": [ { "$month": "$createdAt" }, month ] },
"$$KEEP",
"$$PRUNE"
]
}
}
])
针对其他请求
var day = 17;
db.collection.aggregate([
{
"$redact": {
"$cond": [
{ "$eq": [ { "$dayOfMonth": "$createdAt" }, day ] },
"$$KEEP",
"$$PRUNE"
]
}
}
])
var month = 11,
day = 17;
db.collection.aggregate([
{
"$redact": {
"$cond": [
{
"$or": [
{ "$eq": [ { "$month": "$createdAt" }, month ] },
{ "$eq": [ { "$dayOfMonth": "$createdAt" }, day ] }
]
},
"$$KEEP",
"$$PRUNE"
]
}
}
])
var month = 11,
day = 17;
db.collection.aggregate([
{
"$redact": {
"$cond": [
{
"$and": [
{ "$eq": [ { "$month": "$createdAt" }, month ] },
{ "$eq": [ { "$dayOfMonth": "$createdAt" }, day ] }
]
},
"$$KEEP",
"$$PRUNE"
]
}
}
])
$redact
运算符包含 $project
和 $match
管道的功能,并将返回所有文档都使用 $$KEEP
与条件匹配,并使用 $$PRUNE
变量从管道中丢弃那些不匹配的文档。
答案 5 :(得分:2)
您可以按日期汇总运营商查找按日期,日期,年份等的日期记录,例如 $ dayOfYear,$ dayOfWeek,$ month,$ year 等< / p>
例如,如果您想要2016年4月创建的所有订单,您可以使用以下查询。
db.getCollection('orders').aggregate(
[
{
$project:
{
doc: "$$ROOT",
year: { $year: "$created" },
month: { $month: "$created" },
day: { $dayOfMonth: "$created" }
}
},
{ $match : { "month" : 4, "year": 2016 } }
]
)
这里创建的是文档中的日期类型字段,而$$ ROOT我们用于在下一阶段将所有其他字段传递给项目,并为我们提供文档的所有详细信息。
您可以根据需要优化上述查询,只是举个例子。要了解有关日期聚合运算符的更多信息,请访问the link。
答案 6 :(得分:0)
您可以使用MongoDB_DataObject包装器执行如下查询:
$model = new MongoDB_DataObject('orders');
$model->whereAdd('MONTH(created) = 4 AND YEAR(created) = 2016');
$model->find();
while ($model->fetch()) {
var_dump($model);
}
OR,类似地,使用直接查询字符串:
$model = new MongoDB_DataObject();
$model->query('SELECT * FROM orders WHERE MONTH(created) = 4 AND YEAR(created) = 2016');
while ($model->fetch()) {
var_dump($model);
}