首页 > 解决方案 > mongoDB对多个字段进行排序

问题描述

“书”集合具有以下字段:

如果一本书有很好score的和大量的votes.

我想先查询所有书籍以返回热门书籍,最初我做了类似的事情:

db.collection('book').find().sort({ score: -1, votes: -1 })

返回这些书:

name | score | votes
--------------------
foo  | 4.9   | 3
bar  | 4.6   | 203223
baz  | 4.3   | 323299

如您所见,第一个返回的结果(名为“foo”的书)有一个很好的score,但很少votes。我想排除它,或者至少不那么重视它。

如何更新以前的查询以同时考虑scorevotes字段?


回答:

我最终使用了:https ://www.quora.com/How-does-IMDbs-rating-system-work#:~:text=The%20formula%20for%20calculating%20the,for%20the%20movie%20% 3D%20(票)

标签: mongodbmongodb-querynode-mongodb-native

解决方案


您可以为此使用加权函数。类似于简化的贝叶斯估计器:https ://en.wikipedia.org/wiki/Bayes_estimator#Practical_example_of_Bayes_estimators

W = (R*v) / (v + m)

其中 W = 加权评分 R 平均评分(分数的值) v 投票 m 赋予先前估计的权重(在这种情况下,分数需要被视为“有效”的最小投票 - 在这种情况下我使用 100但你可以使用任何东西:

foo  | 4.9   | 3
bar  | 4.6   | 203223
baz  | 4.3   | 323299

所以 foo 的加权评分(4.9 * 3)/(3+100) = 14.7/300 = .049 bar 将是(4.6 * 203223) / (203223 + 100) = 4.5977(几乎 4.6) baz 将是(4.3 * 323299) / (323299 + 100) = 4.2987(几乎 4.3,但比 bar 更接近 4.3 是 4.6 因为它有更多的选票)

这里还有一些值:

one    | 4.7   | 90  | 2.226
two    | 4.6   | 100 | 2.3
three  | 4.5   | 110 | 2.357

因此,您可以看到票数越少,得分越高权重越小,但是一旦您远远超过最低票数,得分基本上与平均数相同。

(我简化了维基页面中的计算)


推荐阅读