Swift/Firestore 在排名系统中查询集合
Swift/Firestore Query a Collection in a Ranking System
我逐渐意识到我从 SO 社区学到了很多东西,所以提前感谢您的宝贵时间。
以下是我需要完成的工作的摘要:
假设我在一个 Firestore 集合中有 1,000 个用户,每个用户都有一个关联的分数。用户也可以互相关注。假设 'User A' 需要 运行 查询 he/she 关注的 100 个用户,同时保持每个用户在全球 1,000 个用户中的排名。 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 成为数组而不是集合,您将不必在可能的数百个地方维护相同的 user_id 文档。
假设用户 A、R、D、S、T、(...) 都关注用户 H,这意味着您的用户 H 的文档在任何地方都应该相同。您将不得不使用事务来确保用户排名在任何地方都相同,无论何时发生变化。对于您添加到 user_id 文档的任何新字段,这可能是相同的。
将其扩展到仅 10,000 个用户,您的写入操作数量可能是您真正需要的数量的 100 倍。
通过仅引用数组中的关注用户,过程如下:
- 查询当前用户文档
- (可选):提供一个 UI 按钮以“显示我关注的用户”
- 请求该数组中的文档,并可能按排名排序。
如果你想跳过步骤#2,那么你可以直接查询关注的用户,按排名排序,例如限制为10个结果。然后滚动加载更多或单击下一步。 (搜索 'paginated firestore queries' 或 'firestore query cursors')。
现在,回答您的问题“但是我如何在仅查询被关注的 100 个用户的同时保持全球排行榜中的排名?”...
在这种情况下,我会这样做:
在您的 user_id 文档中引入一个新字段,名为:'followerCount',将其设为整数。
- 每次用户决定关注另一个用户时,我都会将 followed 添加到关注者的“following_users”数组字段中。
- 同时,我会increment被关注用户的'followerCount'
- 如果关注者决定取消关注,我会从“following_users”数组中删除被关注的 user_id 并减少被关注用户的“followerCount”。
旁注,我会使用“Firestore Transactions”(google 它)进行此类操作,以确保它们同时发生。
旁注 #2:在 Firestore 中,您可以递增 -1 来递减。
旁注 #3:在 following_users 数组字段上,我鼓励您使用 FieldValue.arrayUnion 添加 user_id 并使用 FieldValue.arrayRemove 删除它们。
以这种方式构建事物,在您的排行榜上执行查询将非常容易。示例:
await leaderboard_query = db.collection(user_information).where('followerCount', '>', 0).orderBy('user_score');
我逐渐意识到我从 SO 社区学到了很多东西,所以提前感谢您的宝贵时间。
以下是我需要完成的工作的摘要:
假设我在一个 Firestore 集合中有 1,000 个用户,每个用户都有一个关联的分数。用户也可以互相关注。假设 'User A' 需要 运行 查询 he/she 关注的 100 个用户,同时保持每个用户在全球 1,000 个用户中的排名。 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 成为数组而不是集合,您将不必在可能的数百个地方维护相同的 user_id 文档。
假设用户 A、R、D、S、T、(...) 都关注用户 H,这意味着您的用户 H 的文档在任何地方都应该相同。您将不得不使用事务来确保用户排名在任何地方都相同,无论何时发生变化。对于您添加到 user_id 文档的任何新字段,这可能是相同的。
将其扩展到仅 10,000 个用户,您的写入操作数量可能是您真正需要的数量的 100 倍。
通过仅引用数组中的关注用户,过程如下:
- 查询当前用户文档
- (可选):提供一个 UI 按钮以“显示我关注的用户”
- 请求该数组中的文档,并可能按排名排序。
如果你想跳过步骤#2,那么你可以直接查询关注的用户,按排名排序,例如限制为10个结果。然后滚动加载更多或单击下一步。 (搜索 'paginated firestore queries' 或 'firestore query cursors')。
现在,回答您的问题“但是我如何在仅查询被关注的 100 个用户的同时保持全球排行榜中的排名?”...
在这种情况下,我会这样做:
在您的 user_id 文档中引入一个新字段,名为:'followerCount',将其设为整数。
- 每次用户决定关注另一个用户时,我都会将 followed 添加到关注者的“following_users”数组字段中。
- 同时,我会increment被关注用户的'followerCount'
- 如果关注者决定取消关注,我会从“following_users”数组中删除被关注的 user_id 并减少被关注用户的“followerCount”。
旁注,我会使用“Firestore Transactions”(google 它)进行此类操作,以确保它们同时发生。
旁注 #2:在 Firestore 中,您可以递增 -1 来递减。
旁注 #3:在 following_users 数组字段上,我鼓励您使用 FieldValue.arrayUnion 添加 user_id 并使用 FieldValue.arrayRemove 删除它们。
以这种方式构建事物,在您的排行榜上执行查询将非常容易。示例:
await leaderboard_query = db.collection(user_information).where('followerCount', '>', 0).orderBy('user_score');