在Cloud Firestore上创建排行榜方案

时间:2017-10-04 09:15:02

标签: firebase google-cloud-firestore

我正在玩最近推出的Cloud Firestore,我想知道是否可以在集合中获取文档的索引来创建排行榜。

例如,假设我想检索用户在排行榜中的位置。我会做这样的事情:

db.collection('leaderboard').doc('usedId')

在那里,我有一个rank字段来显示该用户在排行榜中的位置。但是,这意味着我必须创建一个云函数来计算每次分数变化时用户的位置。考虑到CRUD操作数量的Firestore费用,这可能非常昂贵。

有更好的方法吗?假设定义一个查询字段(即得分),然后在集合的数组中获取该文档的索引?

2 个答案:

答案 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);
  });
});