Агрегация MongoDB сортируется по-разному в зависимости от проекции - PullRequest
0 голосов
/ 20 января 2020

Я обнаружил странное поведение сортировки в MongoDB, когда закончил курс MongDB M121.

Вы можете проверить коллекцию в этом кластере с помощью

mongo mongodb://cluster0-shard-00-00-jxeqq.mongodb.net:27017,cluster0-shard-00-01-jxeqq.mongodb.net:27017,cluster0-shard-00-02-jxeqq.mongodb.net:27017/aggregations?replicaSet=Cluster0-shard-0" --authenticationDatabase admin --ssl -u m121 -p aggregations --norc

Когда я выполню следующую статистическую сортировку:

var favorites = [
  "Sandra Bullock",
  "Tom Hanks",
  "Julia Roberts",
  "Kevin Spacey",
  "George Clooney"]

db.movies.aggregate([
  {
    $match: {
      "tomatoes.viewer.rating": { $gte: 3 },
      countries: "USA",
      cast: {
        $in: favorites
      }
    }
  },
  {
    $project: {
      _id: 0,
      title: 1,
      "tomatoes.viewer.rating": 1,
      num_favs: {
        $size: {
          $setIntersection: [
            "$cast",
            favorites
          ]
        }
      }
    }
  },
  {
    $sort: { num_favs: -1, "tomatoes.viewer.rating": -1, title: -1 }
  },
  {
    $limit: 10
  }
])

Я получу следующий результат :

{ "title" : "Gravity", "tomatoes" : { "viewer" : { "rating" : 4 } }, "num_favs" : 2 }
{ "title" : "A Time to Kill", "tomatoes" : { "viewer" : { "rating" : 3.6 } }, "num_favs" : 2 }
{ "title" : "Extremely Loud & Incredibly Close", "tomatoes" : { "viewer" : { "rating" : 3.5 } }, "num_favs" : 2 }
{ "title" : "Charlie Wilson's War", "tomatoes" : { "viewer" : { "rating" : 3.5 } }, "num_favs" : 2 }
{ "title" : "The Men Who Stare at Goats", "tomatoes" : { "viewer" : { "rating" : 3 } }, "num_favs" : 2 }

Но если я немного изменю проекцию, с:

    $project: {
      _id: 0,
      title: 1,
      "tomatoes.viewer.rating": 1,

На

    $project: {
      _id: 0,
      title: 1,
      rating: "$tomatoes.viewer.rating",

или если я избавлюсь от рейтинга все вместе:

    $project: {
      _id: 0,
      title: 1,

Результирующая сортировка также изменится:

{ "title" : "The Men Who Stare at Goats", "rating" : 3, "num_favs" : 2 }
{ "title" : "Gravity", "rating" : 4, "num_favs" : 2 }
{ "title" : "Extremely Loud & Incredibly Close", "rating" : 3.5, "num_favs" : 2 }
{ "title" : "Charlie Wilson's War", "rating" : 3.5, "num_favs" : 2 }
{ "title" : "A Time to Kill", "rating" : 3.6, "num_favs" : 2 }

Обратите внимание, что mov ie Gravity больше не является лучшим результатом.

Кто-нибудь поймет, почему сортировка будет меняться в зависимости от проекции? Я не ожидал, что проекция вызовет какие-либо изменения в сортировке.

1 Ответ

0 голосов
/ 29 января 2020

Поскольку в проекцию не входит tomatoes.viewer.rating, sort() предполагает, что это null, а затем сортирует поле на основе null вместо фактических значений.

Чтобы решить, просто включите поле в проекцию, чтобы избежать такого поведения.

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