Вопрос или проблема
Я ищу элементы, когда дата находится между двумя датами, используя агрегат MongoDB с оператором $match
.
const ArticleSchema = new Schema<Article>({
slug: {
type: String,
required: true,
unique: true
},
title: {
type: String,
required: true
},
description: {
type: String,
}
},{
timestamps: true
})
С помощью timestamps
автоматически создаются createdAt
и updatedAt
, в конце я создал несколько документов.
[
{
_id:66e9669d93287d09570171e5,
slug:"5oec5rov5a6i5rov5omt5yr5pav6jkc6iqs",
title:"новый заголовок",
description:"",
createdAt:2024-09-17T11:23:09.147+00:00,
updatedAt:2024-09-17T11:23:09.160+00:00
}
]
Пытаюсь найти все документы с помощью $match
:
const query = [
{
$match : {
}
}
];
await collection.aggregate(query);
Это может успешно вернуть документы.
Но когда пытаюсь найти все документы с помощью $match
между датами, вот значения timestart
и timeend
: 2024-08-15T16:00:00.000Z
, 2024-10-02T08:37:41.886Z
. Это должно вернуть несколько документов в указанный промежуток.
export async function trendByTime( timeStart:Date, timeEnd: Date ){
const query = [
{
$match : {
createdAt : { $gte : timeStart, $lt: timeEnd }
}
}
];
await collection.aggregate(query);
}
Но это всегда возвращает пустые документы, у меня нет идей, что не так.
Ответ или решение
Проблема, с которой вы сталкиваетесь при использовании оператора $match
в агрегации MongoDB для фильтрации документов по датам, может быть связана с несколькими аспектами, включая формат данных и логику запроса. Давайте рассмотрим, как правильно настроить ваш запрос и выявить возможные проблемы.
-
Проверка формата дат: Убедитесь, что переменные
timeStart
иtimeEnd
, которые вы используете, действительно являются объектами типаDate
. Если вы передаете строки или другие форматы, это может привести к некорректному выполнению запроса.Например, прежде чем использовать их в запросе, убедитесь, что они правильные:
console.log(timeStart); // Убедитесь, что это экземпляр Date console.log(timeEnd); // Убедитесь, что это экземпляр Date
-
Проверка полей: Убедитесь, что поле
createdAt
в ваших документах действительно хранит значения, которые можно сравнивать. Проверьте, что в вашей базе данных есть документы с правильными метками времени, которые попадают в указанный диапазон.Например, вы можете выполнить простое
find
для проверки наличия документов:const count = await collection.find({ createdAt: { $gte: new Date('2024-08-15T16:00:00.000Z'), $lt: new Date('2024-10-02T08:37:41.886Z') } }).count(); console.log(count); // Если результат 0, значит, документов нет.
-
Правильный запрос: Ваша структура запроса выглядит корректно, но вы можете добавить оператор
$expr
, чтобы убедиться в корректной интерпретации дат, хотя это обычно не требуется:const query = [ { $match : { createdAt : { $gte : timeStart, $lt: timeEnd } } } ];
При этом не забудьте, что
timeStart
иtimeEnd
должны быть типаDate
. -
Дебаггинг: Если после всех проверок ваши документы по-прежнему не возвращаются, попробуйте вывести сам запрос перед выполнением и убедитесь, что он формируется правильно:
console.log(JSON.stringify(query, null, 2)); // Посмотрите на сформированный запрос
-
Проверка индексов: Убедитесь, что у вас есть индексы на поле
createdAt
. Это может помочь в производительности и точности выборки данных. -
Дополнительные проверки: Убедитесь, что в коллекции есть документы, созданные в это время, проверив минимальные и максимальные значения полей
createdAt
:const minDoc = await collection.findOne({}, { sort: { createdAt: 1 } }); const maxDoc = await collection.findOne({}, { sort: { createdAt: -1 } }); console.log({ minDoc, maxDoc }); // Это поможет увидеть диапазон
После выполнения вышеперечисленных шагов вы должны получить правильный набор данных. Если проблема все еще сохраняется, возможно, стоит проверить настройки вашего MongoDB или переустановить соединение с базой данных.