我正在玩最近推出的Cloud Firestore,我想知道是否可以在集合中获取文档的索引来创建排行榜。
例如,假设我想检索用户在排行榜中的位置。我会做这样的事情:
db.collection('leaderboard').doc('usedId')
在那里,我有一个rank
字段来显示该用户在排行榜中的位置。但是,这意味着我必须创建一个云函数来计算每次分数变化时用户的位置。考虑到CRUD操作数量的Firestore费用,这可能非常昂贵。
有更好的方法吗?假设定义一个查询字段(即得分),然后在集合的数组中获取该文档的索引?
答案 0 :(得分:1)
除了通过实际运行查询并阅读所有查询之外,您无法在查询结果中找到文档的位置。这使得按分数排序对于确定排名而言不可行。
您可以通过将排名分组为10或100的块来减少更新排名的写入次数,然后仅在玩家在它们之间移动时更新排名组。绝对等级可以通过按组内的分数排序来确定。
如果您将这些排名组存储为单个文档,则可以节省大量资金。
请注意,随着您增加文档编写者的数量,这会增加争用,因此您需要平衡群组大小与预期分数提交率以获得所需结果。
aggregation queries中的技术可以适应这个问题,但它们基本上与您在问题中描述的成本权衡相同。
答案 1 :(得分:0)
您可以在数据库控制台中对其进行过滤。中心列的右上角,3 个垂直点旁边。
您还可以使用此 GitHub 存储库搜索需要插入代码的查询:https://github.com/firebase/snippets-web/blob/f61ee63d407f4a71ef9e677284c292b0a083d723/firestore/test.firestore.js#L928-L928
例如,如果您想根据用户的“高分”对用户进行排名,您可以对前 10 名使用类似以下内容(并创建一个有序列表或类似列表,以表示用户的排名):
db.collection("leaderboard")
.orderBy("highScore", "desc").limit(10) // this is the line you add to filter results
.get()
.then((snapshot) => {
snapshot.docs.forEach((doc) => {
console.log(doc.data());
renderLeaderboard(doc);
});
});