#mongodb
#mongodb
Вопрос:
Я создаю API для возврата результатов, сгруппированных с использованием Status.
В MongoDB у меня есть записи, содержащие следующие поля:
{
id: Integer,
Status: String,
Subject: String,
Date: Date
}
Я использую следующий агрегированный запрос для извлечения результатов, сгруппированных на основе «Статуса».
db.aggregate([
{
$group: {
_id: '$Status',
count: { $sum: 1 },
tickets: { $push: '$$ROOT' }
}
}
])
Мне нужно показывать только 10 записей в каждой группе одновременно.
Я использую MongoDB 3.6
Как я могу реализовать разбивку на страницы сгруппированных результатов, возвращаемых этим агрегированным запросом?
Ответ №1:
skip(n) пропускает n документов из курсора, в то время как limit (n) ограничивает количество документов, которые должны быть возвращены из курсора. Таким образом, комбинация двух естественным образом разбивает ответ на страницы.
//Get count from the query params
let limit = parseInt(req.query.count) || 10;
//Get pageNumber from the query params
let pageNumber = parseInt(req.query.pageNumber) || 1;
if (pageNumber < 1 || limit < 1) res.json([]); // Return empty
let skip = (pageNumber - 1) * limit;
let searchConditions = [ { $group: { _id: '$Status', count: { $sum: 1 }, tickets: { $push: '$$ROOT' } } } ];
db.aggregate(searchConditions)
.skip(skip)
.limit(limit)
Комментарии:
1. Спасибо за ответ. Но это не разбивка на страницы сгруппированных результатов. После того, как результат агрегированного запроса будет выглядеть следующим образом: [{_id:»Open»,count: 123,tickets:[ {} ] },{_id:»Close»,count: 623,tickets:[ {} ] } ] Массив Tickets в каждой группе будет содержать все билеты этой группы. Я хочу разбить здесь на страницы таким образом, чтобы массив tickets в каждой группе содержал одновременно только 10 билетов, не влияя на количество.
Ответ №2:
Я думаю, что это невозможно сделать во время отправки.
Если приведенный ниже результат неверен, попробуйте с
Query when pagination button click with skip and limit
Попробуйте это. Не знаю, поможет ли это вам.
и я не знаю, правильный ли это метод.
db.collection.aggregate([
{
$group: {
_id: '$Status',
count: { $sum: 1 },
tickets: { $push: '$$ROOT' }
}
},
{
$addFields:{
tickets:{ $slice: [ "$tickets", 2,3] }
}
}
])
2,3 — это позиция и количество возвращаемых данных соответственно.
Просто попробуйте.
Я попробую другой метод без среза.
Комментарии:
1. Нарезка будет работать после этапа $ group, верно? Возможно ли это сделать на самом этапе $ group?
2. На самом деле
slice
это не метод дляskip
иlimit
. Здесьslice
используется для обозначения количества элементов массива, возвращаемых запросом.3. У меня около 1 миллиона записей. Для каждого следующего запроса страницы он будет сканировать все 1 миллион записей, и только тогда он будет применять фрагмент правильно?
4. Я думаю, что это невозможно сделать во время отправки. Мы можем выполнить поиск по нему.
5. Да, вы правы. Мне нужна разбивка на страницы на самом этом этапе ($ group). Спасибо за вашу поддержку.