当我完成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.rating
,所以sort()
会假定它是null
,然后根据null
而不是实际值对字段进行排序。
要解决,只需在投影中包括该字段即可避免此行为。