Я заметил, что подсчет документов с использованием агрегата с $ lookup и $ count выполняется довольно медленно (~ 1,4 секунды для сбора с локальным запуском 20 тыс. Документов), где без $ lookup это занимает ~ 14 мс.Относительно индексов: foreginField поиска - _id
, и чтобы быть в безопасности, я также создал индекс для "localField".Является ли такая производительность "нормальной"?
MongoDB версии 4.2.0 на компьютере Windows с драйвером Node.JS.
Вот мой тестовый код:
var mongo = require('mongodb');
async function start() {
console.log('Connecting...');
var client = await mongo.MongoClient.connect('mongodb://test:test@127.0.0.1:27017/test', { useNewUrlParser: true, useUnifiedTopology: true });
var db = client.db();
console.log('Creating data...');
await db.collection('users').drop();
var res = await db.collection('users').insertOne({name: 'user', email: 'user@test.com'});
var projects = Array(20000).fill().map((x, i) => ({ name: `project-${i}`, user: res.insertedId }));
await db.collection('projects').drop();
await db.collection('projects').insertMany(projects);
await db.collection('projects').createIndex({user: 1}, {name: 'user_1'});
await runAggregate(db, 'Fetching with $lookup...', [
{$lookup: {from: 'users', localField: 'user', foreignField: '_id', as: 'user'}},
{$match: {/* In real I will have here some query involving fields from user */}},
{$count: 'total'}
]);
await runAggregate(db, 'Fetching without $lookup...', [
{$match: {/* In real I will have here some query involving fields from user */}},
{$count: 'total'}
]);
}
async function runAggregate(db, msg, agg) {
console.log('Waiting 2 seconds...');
await wait(2000)
console.log(msg);
var start = Date.now();
var res = await db.collection('projects').aggregate(agg);
res = await res.toArray();
var span = Date.now() - start;
console.log('Aggregate took: %s msec', span);
}
function wait(ms) {
return new Promise(res => setTimeout(res, ms));
}
start().then(process.exit);
И этоэто вывод:
Connecting...
Creating data...
Waiting 2 seconds...
Fetching with $lookup...
Aggregate took: 1429 msec
Waiting 2 seconds...
Fetching without $lookup...
Aggregate took: 14 msec
Спасибо.