У меня есть конвейер агрегации mongo DB, который выполняет следующие шаги:
- Сортирует список объектов статистики пользователя по отметке времени
- Группирует результаты по идентификатору пользователя
- Сортировка по указанному имени статистики
- Страницы результатов через этапы пропуска и ограничения
На простом английском этот конвейер возвращает страницу из списка статистики пользователя, отсортированной по указанномустат.У каждого пользователя может быть несколько объектов статистики, поэтому я группирую, чтобы вернуть только самый последний объект статистики для каждого пользователя.
В Mongo Shell это выглядит следующим образом:
db.getCollection("stats").aggregate(
[
{ "$sort" : { "Timestamp" : -1.0 } },
{
"$group" : {
"_id" : "$UserId",
"UserId" : { "$last" : "$UserId" },
"StatsOverall" : { "$last" : "$StatsOverall" },
"Timestamp" : { "$last" : "$Timestamp" }
}
},
{ "$sort" : { "StatsOverall.Rank" : -1.0 } },
{ "$skip" : specifiedPageNumber },
{ "$limit" : specifiedNumResultsPerPage }
]
);
Это прекрасно работает.
Теперь я хочу изменить этот запрос, чтобы иметь возможность искать пользователя по имени и возвращать всю страницу, на которой содержится пользователь.(Это для лидеров).Итак, если пользователь находится на странице 5 списка лидеров, я хочу вернуть всю страницу 5.
Однако у меня возникают проблемы с поиском решения, которое не требует от меня загрузки всехпользователи в памяти и там пейджируют их (ужасная идея), или переходят туда и обратно в базу данных, перебирая страницы (почти так же ужасно).
Есть ли какой-то способ, которым я могу изменить свой конвейер агрегации, чтобы сделать всеэто на уровне базы данных?
РЕДАКТИРОВАТЬ: В соответствии с запросом, добавил некоторые примеры данных и ожидаемый результат.
Пример данных выглядит примерно так ... Я пропустил некоторые поля, которые не 'т актуален.Исходные данные представляют собой набор статистики пользователя, где каждый пользователь может иметь более одного объекта.Мой существующий конвейер возвращает 1 самый последний объект статистики для каждого пользователя, отсортированный по указанному имени статистики.
{
"_id" : "5c611e71ab0ffc430410e0ba",
"UserId" : "5c611e71ab0ffc430410e0ba",
"StatsOverall" : {
"Rank" : NumberInt(1000),
"GamesLost" : NumberInt(30),
"GamesWon" : NumberInt(50)
}
"Timestamp" : "2019-02-10T21:35:06.599Z"
}
// ----------------------------------------------
{
"_id" : "5c6238658966ae5860795879",
"UserId" : "5c6238658966ae5860795879",
"StatsOverall" : {
"Rank" : NumberInt(413),
"GamesLost" : NumberInt(2),
"GamesWon" : NumberInt(141),
},
"Timestamp" : "2019-02-10T21:35:06.599Z"
}
// many objects like this
Ожидаемый результат выглядит следующим образом:
{
"_id" : "5c611e71ab0ffc430410e0ba",
"UserId" : "5c611e71ab0ffc430410e0ba",
"StatsOverall" : {
"Rank" : NumberInt(1000),
"GamesLost" : NumberInt(30),
"GamesWon" : NumberInt(50)
}
"Timestamp" : "2019-02-10T21:35:06.599Z"
}
Возвращает точно такой же тип объекта, отсортированный так же, как существующий конвейер, однако я хочу вернуть толькостраница, на которой находится пользователь.В примере результата предположим, что размер страницы составляет всего 1 результат на страницу.Таким образом, результат будет содержать 1 страницу, на которой находится пользователь с указанным UserId
.В моем примере результата этот идентификатор будет 5c611e71ab0ffc430410e0ba
.