Монго Агрегирование нескольких этапов сортировки (nodejs) - PullRequest
0 голосов
/ 23 января 2019

Я пытаюсь построить сложный конвейер агрегации, который будет извлекать элементы из коллекции и сортировать их несколько раз.

Что мне нужно, это: 1) получить всех пользователей из коллекции 2) сортировать их по выбранному пользователем значению (например, по количеству оставленных комментариев) 3) сортировать их по роли (администратор, модератор, обычный пользователь)

Идея состоит в том, чтобы сначала показать пользователя-администратора, даже если у некоторого основного пользователя есть больше комментариев, но если у нас есть 2 администратора - они также будут отсортированы.

Обратите внимание, что первая сортировка $ должна избежать неожиданного поведения сортировки + ограничения, когда элементы не выбираются в постоянном порядке. Значение $ skip вычисляется при построении конвейера в зависимости от номера страницы, переданного в запросе API.

Пока у меня есть что-то вроде этого:

[
  { $match: <some condition> },
  { $sort: { _id: 1 } },
  { $sort: { countOfComment: -1 } },
  { $sort: { isAdmin: -1, isModerator: -1 } },
  { $skip: <page * 10> },
  { $limit: 10 }
]

Если я правильно понял - он должен: 1) отсортировать всех пользователей по идентификатору, чтобы не было дубликатов на разных страницах. это требует уникального поля для работы 2) сортировать по количеству комментариев 3) сортировка по роли пользователя. Это означало сохранить предыдущие результаты сортировки, поэтому

- user with 4 comments
- moderator with 0 comments
- admin with 3 comments
- user with 2 comments
- admin with 1 comment

станет

- admin with 3 comments
- admin with 1 comment
- moderator with 0 comments
- user with 4 comments
- user with 2 comments

Но это не так. Похоже, что каждый следующий оператор $ sort теряет результаты предыдущего. Есть идеи, как достичь желаемого поведения?

Ответы [ 2 ]

0 голосов
/ 23 января 2019

Вы можете объединить сортировку в один объект, например: -

{ $sort: { countOfComment: 1, isAdmin: -1, isModerator: -1 } }

Вы можете использовать $ group для удаления повторяющихся записей, а затем использовать проект и после этого использовать сортировку

0 голосов
/ 23 января 2019

Вам нужен только один этап сортировки, то есть

    $sort: {
      isAdmin: -1,
      isModerator: -1,
      countOfComment: -1
    }

По сути, так как вы сначала отсортировали по countOfComment, тогда наивысший приоритет будет отдан сортировке по countOfComment.Таким образом, несмотря ни на что, поле countOfComment определенно будет отсортировано в порядке убывания, и только тогда оно увидит следующее поле для сортировки.Аналогично, последнее поле будет иметь наименьший приоритет при сортировке.

Порядок, в котором вы размещаете элементы сортировки, является порядком приоритета.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...