#mongodb #mongoose
#mongodb #mongoose
Вопрос:
Я работаю над функциональностью, в которой мне нужно сохранять документы mongodb между датами.
Я вообще не хочу сравнивать временные метки, чтобы получить данные.
Вот образец данных, которые у меня есть.
Образец данных:
/* 1 */
{
"_id" : ObjectId("5fb266103d41cc0a686b02e8"),
"projectId" : "80674480738",
"hum" : 20,
"temp" : 40,
"deviceId" : "DEV-1",
"entryDayTime" : ISODate("2020-11-16T11:44:16.443Z")
}
/* 2 */
{
"_id" : ObjectId("5fb265fda153fb1a446bff4a"),
"projectId" : "80674480738",
"hum" : 20,
"temp" : 40,
"deviceId" : "DEV-1",
"entryDayTime" : ISODate("2020-11-16T11:43:57.148Z")
}
/* 3 */
{
"_id" : ObjectId("5fb26599e876dc2428f54ca4"),
"projectId" : "80674480738",
"hum" : 20,
"temp" : 40,
"deviceId" : "DEV-1",
"entryDayTime" : ISODate("2020-11-14T11:42:17.629Z")
}
/* 4 */
{
"_id" : ObjectId("5fb265616151552660d3799f"),
"projectId" : "80674480738",
"hum" : 20,
"temp" : 40,
"deviceId" : "DEV-1",
"entryDayTime" : ISODate("2020-11-14T11:41:21.590Z")
}
Теперь я хочу получить документы, сохраненные на 11-14-2020 (mm-dd-yyyy format)
.
Ниже приведен запрос, который я использую.
Запрос:
mongoose.connection.db.collection('80674480738')
.aggregate([
{
$match: {
"entryDayTime": {
$lte: "2020-11-14T18:30:00.000Z",
$gte: "2020-11-14T18:30:00.000Z"
}
}
},{
$sort:{"_id":-1}
}
]).toArray();
Ожидаемый результат:
{
"_id" : ObjectId("5fb26599e876dc2428f54ca4"),
"projectId" : "80674480738",
"hum" : 20,
"temp" : 40,
"deviceId" : "DEV-1",
"entryDayTime" : ISODate("2020-11-14T11:42:17.629Z")
},
{
"_id" : ObjectId("5fb265616151552660d3799f"),
"projectId" : "80674480738",
"hum" : 20,
"temp" : 40,
"deviceId" : "DEV-1",
"entryDayTime" : ISODate("2020-11-14T11:41:21.590Z")
}
Используя приведенный выше запрос, я не получаю результата.
После отладки кода я обнаружил, что конфликт возникает из-за временных меток.
Итак, теперь я хочу только сравнить dates but not timestamps
, чтобы получить результат.
Есть ли какой-нибудь способ сделать это?
Ответ №1:
Условие "entryDayTime": { $lte: "2020-11-14T18:30:00.000Z", $gte: "2020-11-14T18:30:00.000Z" }
означает, что вы выбираете документ точно и только в "2020-11-14T18:30:00.000Z"
Попробуйте
{
$match: {
"entryDayTime": {
$lte: ISODate("2020-11-14T23:59:59.999Z"),
$gte: ISODate("2020-11-14T00:00:00.000Z")
}
}
}
Или вы могли бы использовать moment.js библиотека:
{
$match: {
"entryDayTime": {
$lte: moment("2020-11-14T18:30:00.000Z").endOf('day').toDate(),
$gte: moment("2020-11-14T18:30:00.000Z").startOf('day').toDate()
}
}
}
Комментарии:
1. Я попробовал 2-й подход, но результат не возвращается, и временные метки выглядят одинаково, @Wernfried Domscheit
2. Невозможно ли выполнять поиск только по датам?
3. Это значения, которые я напечатал на консоли,
entryDayTime: { '$lte': 2020-11-15T18:30:00.000Z, '$gte': 2020-11-15T18:30:00.000Z }
4.
"2020-11-15T18:30:00.000Z"
является строкой — вы должны сравниватьDate
объекты со значениями даты .5. Вы имеете в виду
$lte: moment("2020-11-14").endOf('day').toDate(), $gte: moment("2020-11-14").startOf('day').toDate()
?
Ответ №2:
Это может быть экзотическим способом, но должно сработать
.aggregate([
{
"$set": {
"entryDate": {
"$toDate": {
"$subtract": [
{ "$toLong": "$entryDayTime" },
{ "$mod": [ { "$toLong": "$entryDayTime" }, 86400 * 1000] }
]
}
}
}
},
{
"$match": {
"entryDate": ISODate("2020-11-14")
}
},
{
"$sort": {
"_id": 1
}
}
]);
На первом этапе будет создано новое entryDate
поле.
На втором этапе будут отфильтрованы те записи, которые имеют соответствие entryDate
.
На третьем этапе будет произведена сортировка записей по _id
.
Это не так просто, как приведенный ниже запрос, но должно работать.
.find({
"entryDayTime": {
"$gte": ISODate("2020-11-14"),
"$lt": ISODate("2020-11-15")
}
}).sort({
"_id": 1
});
Комментарии:
1. Спасибо @Andrew Неясно. Так работает ли 2-й подход? Или я должен использовать 1-й для сравнения только с датами?
2. @Aravind обе работы работают для меня. Я бы использовал первый, только если мне нужно добавить больше этапов агрегации.