Агрегат MogoDB с ожидаемой производительностью $ count и $ lookup - PullRequest
0 голосов
/ 25 сентября 2019

Я заметил, что подсчет документов с использованием агрегата с $ 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

Спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...