Я хочу использовать фасет для создания простого запроса, который я могу использовать для получения выгружаемых данных, однако я заметил, что если я это сделаю, то получаю очень низкую производительность по сравнению с выполнением всего двух отдельных запросов.
В качестве быстрого теста я создал коллекцию из 50000 случайных документов и выполнил следующий тест.
var x = new Date();
var a = {
count : db.getCollection("test").find({}).count(),
data: db.getCollection("test").find({}).skip(0).limit(10)
};
var y = new Date();
print('result ' + a);
print(y - x);
var x = new Date();
var a = db.getCollection("test").aggregate(
[
{
"$match" : {
}
},
{
"$facet" : {
"data": [
{
"$skip": 0
},
{
"$limit": 10
}
],
"pageInfo": [
{
"$group": {
"_id": null,
"count": {
"$sum": 1
}
}
}
]
}
}
]
)
var y = new Date();
print('result ' + a);
print(y - x);
Результатом этого является то, что два отдельных запроса один для поиска, другой для подсчета занимает около 2 миллисекунды против одного запроса агрегации, занимающего более 500 миллисекунд .
Почему агрегация такая медленная?
Обновление
Даже простой подсчет без фасета в агрегации медленен
var x = new Date();
var a = db.getCollection("test").find({}).count();
var y = new Date();
print('result ' + a);
print(y - x);
var x = new Date();
var a = db.getCollection("test").aggregate(
[
{ "$count" : "count" }
]
)
var y = new Date();
print('result ' + a);
print(y - x);
В приведенном выше примере с моим набором тестовых данных агрегационный счет занимает 200 мс против метода подсчета, принимающего 2 мс .
Эта проблема распространяется на драйвер Mongodb NodeJs, где метод .Count () объявлен устаревшим и заменен методом countDocuments (), а внутри нового метода countDocuments () используется агрегация, а не метод count в найти, как и в моем примере выше, он имеет значительно худшую производительность до того момента, когда я продолжу использовать устаревший метод по сравнению с более новым методом countDocuments ().