由于排名是根据帖子创建后的时间和帖子获得的分数计算得出的值,因此您实际上只有两个选择。您可以获取所有帖子并在客户端计算排名(在您的情况下这不是一个选项),或者您可以在对帖子进行更新时计算排名。另外,我在 Swift 中给出了我的例子。
本示例的数据库结构:
posts : {
$post: {
stats : {
score : scoreValue,
ranking : rankingValue,
createdAt : timestamp
}
}
}
具体而言,这意味着当创建新帖子时,您将为它分配默认分数并计算排名。
由于排名现在存储在数据库中,您可以使用简单地获取前 x 个帖子
postsRef.queryOrdered(byChild:"stats/ranking").queryLimited(toLast: x)
或许
ref.queryOrdered(byChild: "stats/ranking").queryEnding(atValue: "lowestScoreSoFar").queryLimited(toLast: x)
现在,为了确保帖子的排名保持最新,您只需在更新分数的同一操作(交易)中更新排名。
ref.runTransactionBlock({ (currentData: FIRMutableData) -> FIRTransactionResult in
if var stats = currentData.value as? [String : Any] {
var score = stats["score"] as? Int
var createdAt = stats["createdAt"] as? Long
score += 1
var ranking = calculateRanking(score, createdAt)
stats["score"] = score
stats["ranking"] = ranking
currentData.value = stats
return FIRTransactionResult.success(withValue: currentData)
}
return FIRTransactionResult.success(withValue: currentData)
}) { (error, committed, snapshot) in
if let error = error {
print(error.localizedDescription)
}
}
这种方法的一个问题是,如果没有人投票,得分高的帖子会一直浮动在顶部。为了应对这个黑客新闻,他们似乎在他们的服务器上运行了一个脚本,该脚本每 30 秒更新一个随机帖子在前 x 中的排名。您必须运行服务器并查看哪种设置最适合您的特定情况。
如果您使用类似于 Hacker News 的算法,所有帖子的评分将趋向于 0,因此您可以尝试随机更新排名高于某个阈值的帖子的排名(这样您将忽略较旧且不相关的帖子)。
Hacker News Algorithm
More info on the algorithm
How often does Hacker News recalculate rankings
How Hacker News algorithm really works