Я пытался написать функцию поиска, которая принимает массив с идентификаторами объектов и временными метками объекта y.Это сработало безупречно с localflied
и foreignfield
, но я не могу воспроизвести тот же результат с использованием конвейера.
(имена, подобные y
, составлены так, чтобы оно было общим)
Рабочая версия:
$lookup: {
from: 'y',
localField: 'ys.object_id',
foreignField: '_id',
as: 'docs',
},
ys
- это массив объектов, структурированных так:
{
object_id: ObjectID(),
timestamp: Date(),
}
Я хотел бы переписать это выражение, чтобы использовать конвейер, потому что я уже хочу отфильтровать некоторые объектыпосмотрел, используя их атрибут timestamp.
То, что я пробовал:
$lookup: {
from: 'y',
let: { ys: '$ys' },
pipeline: [
{
$match: { $expr: { $eq: ['$_id', '$$ys.object_id'] } },
},
],
as: 'docs',
},
Размер базы данных: 20.4GB
Полный запрос:
const query = [
{
$match: { 'ys.timestamp': { $lte: date, $gt: previousMonth } }, // I have shorten this part a little (It's not the same but the logic was flawed anyway)
},
{
$limit: 100,
},
{
$lookup: {
from: 'y',
let: { ys: '$ys' },
pipeline: [
{
$match: { $expr: { $in: ['$_id', '$$ys.object_id'] } },
},
{
$sort: { timestamp: -1 },
},
{
$limit: 1,
},
],
as: 'doc',
},
},
];
Приведенное выше решение не работает, похоже, застревает и никогда ничего не возвращает.(Время истекает через некоторое время)
Существует ли правильный способ переписать рабочее решение в конвейерное решение?
ВАЖНО : Я изменил запрос для поискаодин конкретный элемент по идентификатору, а затем выполнить поиск.Это действие сработало, но заняло около 20 секунд.Я вполне уверен, что именно поэтому мой запрос истекает, когда я запускаю его с моим обычным запросом.Кто-нибудь может объяснить, почему существует разница в производительности между этими двумя подходами, и если я могу как-то обойти это?