Как найти и вернуть страницу, на которой находится результат, в конвейере агрегации MongoDB? - PullRequest
0 голосов
/ 05 марта 2019

У меня есть конвейер агрегации 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.

...