MongoDB 聚合排序因投影而异

MongoDB Aggregation Sort Differently Depending on Projection

当我完成 MongDB 课程 M121 时,我从 MongoDB 中发现了一个奇怪的排序行为。

您可以使用

测试此集群中的集合
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 }

请注意电影《地心引力》不再是最佳结果。

谁能理解为什么排序会根据投影发生变化?我没想到投影会导致排序发生任何变化。

由于投影不包括 tomatoes.viewer.ratingsort() 会假设它是 null,然后根据 null 而不是实际值对字段进行排序。

要解决这个问题,只需将场包括在投影中即可避免此行为。