#mongodb
Вопрос:
У меня есть агрегация фасетов в mongodb. Это работает. Теперь мне нужно ограничить результат, чтобы получить бесконечный свиток. Как получить общее количество совпадающих документов во всей коллекции?
Я могу получить общее количество документов в коллекции, но это число не имеет значения. Моя цель-узнать, может ли пользователь получить больше данных. Если он получил 120 документов, но 150 соответствуют его фильтру, то можно выполнить другой запрос.
Вот мой вопрос:
db.collection.aggregate([
{
$facet: {
data: [
{ $match: { score: {$gt: 80 } } },
{ $skip: 0},
{ $limit: 2},
{ $project: { score: 1 } }
],
}
},
])
Вы можете играть с поддельными данными в этой песочнице: https://mongoplayground.net/p/EClbe0f_Fms
Реальное количество совпадающих документов равно 4. Если я добавлю «хиты» после фасета с оператором $count, я получу 7, что составляет общее количество документов. Как эффективно получить эту информацию?
Ответ №1:
Наиболее эффективным способом было бы вообще не использовать $count, а скорее проверить, была ли последняя полученная страница меньше лимита. То есть:
const perPage = 10;
const results = await getPageOfResults();
const atEnd = results.length < perPage;
Похоже, вы уже добавили $count в свой фасет, но получили неверный результат. Чтобы получить «реальное» количество совпадающих документов, вам нужно добавить этап $match к обоим аспектам, например https://mongoplayground.net/p/liQaiyZhYER
db.collection.aggregate([
{
$facet: {
data: [
{ $match: { score: {$gt: 80 } } },
{ $skip: 0},
{ $limit: 2},
{ $project: { score: 1 } }
],
count: [
{ $match: { score: {$gt: 80 } } },
{ $count: 'total' }
]
}
},
{$unwind: "$count"},
{$addFields: {
count: "$count.total"
}}
])
Комментарии:
1. Хорошо, спасибо за вашу проницательность! В конце концов, я думаю, что просто сделаю два отдельных запроса: один, чтобы получить общую сумму, а затем запрос. Таким образом, общая сумма будет рассчитана только один раз, и я проверю эту информацию в интерфейсе.