swift - Swift/Firestore 在排名系统中查询集合
问题描述
我已经很感激我从 SO 社区学到了很多东西,所以提前感谢您抽出宝贵的时间。
以下是我需要完成的摘要:
假设我在 Firestore 集合中有 1,000 个用户,每个用户都有一个相关的分数。用户也可以互相关注。假设“用户 A”需要对他/她关注的 100 个用户运行查询,同时保持每个用户在全球 1000 个用户中的排名。IE 用户 A 关注排名#1 的人、排名#237 的人、排名#999 的人等。
我的数据目前的结构如下所示:
user_information (Collection)
-- user_id (Document)
---- user_score (Int Field) <- the field in which the query is sorted by
users (Collectiion)
-- user_id (Document)
---- following_users (Collection) <- Running the query on these users
------ user_id (Document)
可以很容易地following_users
根据他们的分数进行排序,但是如何在仅查询被关注的 100 个用户的同时保持全球排行榜中的排名?我需要采取不同的方法来完成这样的任务吗?
解决方案
在回答您的最后一个问题之前,让我分享一下:我的方法是通过以下方式调整您的数据库结构:
user_information (Collection)
-- user_id (Document)
---- user_score (Int Field) <- the field in which the query is sorted by
users (Collectiion)
-- user_id (Document)
---- following_users (Array Field) [Array field of user_id's this user is following]
通过将 following_users 设为 Array 而不是集合,您不必在可能数百个地方维护相同的 user_id 文档。
假设用户 A、R、D、S、T、(...) 都关注用户 H,这意味着您的用户 H 的文档应该在任何地方都相同。您必须使用事务来确保用户排名在任何地方都相同,无论何时发生变化。这对于您添加到 user_id 文档的任何新字段都可能相同。
将其扩展到仅 10,000 个用户,您的写入操作数量可能是您真正需要的数量的 100 倍。
通过仅引用数组中的关注用户,过程将如下所示:
- 查询当前用户文档
- (可选):为“显示我关注的用户”提供一个 UI 按钮
- 请求该数组中的文档,并可能按等级排序。
如果您想跳过步骤#2,那么您可以直接查询关注的用户,按排名排序,例如限制为 10 个结果。然后滚动以加载更多或单击下一步。(搜索“分页 Firestore 查询”或“Firestore 查询游标”)。
现在,回答您的问题“但是如何在仅查询被关注的 100 个用户的同时保持全球排行榜中的排名? ”...
在这种情况下,我会这样做:
在您的 user_id 文档中引入一个新字段,称为:'followerCount',将其设为 Integer。
- 每次用户决定关注另一个用户时,我都会将关注添加到关注者的“following_users”数组字段中。
- 同时,我会增加被关注用户的“followerCount”。
- 如果关注者决定取消关注,我将从“following_users”数组中删除关注的 user_id,并减少关注用户的“followerCount”。
旁注,我会使用“Firestore Transactions”(google it)进行此类操作,以确保它们同时发生。
旁注 #2:在 Firestore 中,您可以递增 -1 来递减。
旁注#3:在 following_users 数组字段上,我鼓励您使用FieldValue.arrayUnion添加 user_id's 和 FieldValue.arrayRemove 以删除它们。
以这种方式构建事物,在排行榜上执行查询将非常容易。例子:
await leaderboard_query = db.collection(user_information).where('followerCount', '>', 0).orderBy('user_score');
推荐阅读
- c++ - CUDA: Fill matrix with results of summation
- java - 获取用户输入,然后使用 AWT 打印新文本
- javascript - How to fix get request and response with whole html
- symfony - 定义“nelmio_cors”不支持配置键“defaults”
- c# - WPF 组合框似乎导致 InvalidCastException
- mysql - SQL日期间隔不适用于AND子句
- c# - 如果 int 值等于 x 替换为字符串
- android - Putting ImageView in front of other elements < 21API
- reactjs - How to correctly validate an masked-input using material-ui, formik, yup, and react-input-mask?
- java - 编译错误将实例方法声明为静态上下文(Java 6)