У меня есть коллекция, которая имеет около 30 атрибутов, 2 из которых являются отношениями (ObjectId) с 2 другими коллекциями.Мне нужно иметь возможность сортировать родительскую коллекцию по столбцам 2 дочерних коллекций.
Для этого я написал конвейер, который выглядит следующим образом:
Document.aggregate([
{
$match: {
deleted: false,
},
},
{
$lookup:
{
from: 'companies',
localField: 'company',
foreignField: '_id',
as: 'company',
},
},
{
$unwind:
{
path: '$company',
preserveNullAndEmptyArrays: true,
},
},
{
$lookup:
{
from: 'suppliers',
localField: 'supplier',
foreignField: '_id',
as: 'supplier',
},
},
{
$unwind:
{
path: '$supplier',
preserveNullAndEmptyArrays: true,
},
},
{
$sort: { 'company.name': -1 },
},
{
$skip: 0,
},
{
$limit: 10,
}
]);
Проблема в том, что это слишком медленно.В Compass он превышает ограничение по времени, и когда я запускаю его в узле, обработка занимает около 10 секунд.Размер родительской коллекции составляет около 60К.Без этапа сортировки он работает около 25 мс.Кроме того, когда я перемещаю этап сортировки в верхнюю часть конвейера, он работает очень быстро, но результаты не будут правильными, если я хочу отсортировать по атрибуту company.name.Атрибуты «company» и «supplier» в родительской коллекции индексируются.
Я читал, что для того, чтобы на этапе сортировки использовались индексы, его нужно поместить в начало конвейера вместе со стадией 'match', но это не соответствует моему требованиюсортировка по атрибуту дочерней коллекции.Разве это невозможно сделать менее чем за 100 мс?Чего мне не хватает?
РЕДАКТ. 1
Вот объяснение:
{ stages:
[ { '$cursor':
{ query: { state: true },
queryPlanner:
{ plannerVersion: 1,
namespace: 'test.documents',
indexFilterSet: false,
parsedQuery: { state: { '$eq': true } },
winningPlan:
{ stage: 'FETCH',
inputStage:
{ stage: 'IXSCAN',
keyPattern: { state: 1 },
indexName: 'state_1',
isMultiKey: false,
multiKeyPaths: { state: [] },
isUnique: false,
isSparse: false,
isPartial: false,
indexVersion: 2,
direction: 'forward',
indexBounds: { state: [ '[true, true]' ] } } },
rejectedPlans: [] } } },
{ '$lookup':
{ from: 'companies',
as: 'company',
localField: 'company',
foreignField: '_id',
unwinding: { preserveNullAndEmptyArrays: true } } },
{ '$lookup':
{ from: 'suppliers',
as: 'supplier',
localField: 'supplier',
foreignField: '_id',
unwinding: { preserveNullAndEmptyArrays: true } } },
{ '$sort': { sortKey: { 'company.name': -1 }, limit: 10 } } ],
ok: 1 }
В коллекции документов company
, supplier
, state
все поля являются индексами.