Запрос Mongodb на месяц, день, год ... datetime [дубликат]
этот вопрос уже есть ответ здесь:
- найти объекты между двумя датами MongoDB 10 ответов
Я использую 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})
кто знает, как сделать этот запрос?
7 ответов
даты хранятся в формате метки времени. Если вам нужно все, что принадлежит определенному месяцу, запросите начало и конец месяца.
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/
вы не можете прямо запросить коллекции mongodb по компонентам даты, таким как день или месяц. Но это возможно с помощью специального $, где выражение javascript
db.mydatabase.mycollection.find({$where : function() { return this.date.getMonth() == 11} })
или просто
db.mydatabase.mycollection.find({$where : 'return this.date.getMonth() == 11'})
(но я предпочитаю первое)
Проверьте ниже команды оболочки, чтобы получить части даты
>date = ISODate("2011-09-25T10:12:34Z")
> date.getYear()
111
> date.getMonth()
8
> date.getdate()
25
EDIT:
используйте $where, только если у вас нет другого выбора. Оно приходит с представлением проблемы. Пожалуйста, ознакомьтесь с комментариями @kamaradclimber и @dcrosta. Я позволю этому сообщению открыться, чтобы другие люди получили факты об этом.
и проверьте ссылку $where предложения и функции в запросах дополнительная информация
Как насчет хранения месяца в собственном свойстве, так как вам нужно запросить его? менее элегантно, чем $where
, но, вероятно, будет работать лучше, так как его можно индексировать.
Если вы хотите найти документы, относящиеся к определенному месяцу, обязательно выполните запрос следующим образом:
// 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)}});
избегайте quering как ниже, насколько это возможно.
// 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)}});
вы можете запустить агрегатную операцию с помощью aggregate()
функция, которая принимает в $redact
конвейер, который использует Дата Операторы Агрегирования в выражении состояния:
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
pipeline и вернет все документы, соответствующие условию, используя $$KEEP
и отбросить из конвейера те, которые не соответствуют с помощью $$PRUNE
переменной.
вы можете найти запись по месяцам, дням, годам и т. д. дат по Дата Операторы Агрегирования, как $dayOfYear, $dayOfWeek, $месяц, $год etc.
например, если вы хотите, чтобы все заказы, которые создаются в апреле 2016 года вы можете использовать ниже запроса.
db.getCollection('orders').aggregate(
[
{
$project:
{
doc: "$$ROOT",
year: { $year: "$created" },
month: { $month: "$created" },
day: { $dayOfMonth: "$created" }
}
},
{ $match : { "month" : 4, "year": 2016 } }
]
)
здесь создано поле типа даты в документах, и $ $ ROOT мы использовали, чтобы передать все другое поле для проекта на следующем этапе и дать нам все детали документов.
вы можете оптимизация выше запроса в соответствии с вашими потребностями, это просто дать пример. Чтобы узнать больше об операторах агрегации дат, посетите ссылке.
можно использовать MongoDB_DataObject wrapper для выполнения такого запроса, как показано ниже:
$model = new MongoDB_DataObject('orders');
$model->whereAdd('MONTH(created) = 4 AND YEAR(created) = 2016');
$model->find();
while ($model->fetch()) {
var_dump($model);
}
или, аналогично, используя прямую строку запроса:
$model = new MongoDB_DataObject();
$model->query('SELECT * FROM orders WHERE MONTH(created) = 4 AND YEAR(created) = 2016');
while ($model->fetch()) {
var_dump($model);
}