【发布时间】:2019-06-10 02:13:57
【问题描述】:
我有两个 Firestore 集合,Users 和 Posts。以下是每个典型文档所包含内容的简化示例。
*请注意,friends 子集合中的文档 ID 等于相应用户文档的文档 ID。或者,我还可以将uid 字段添加到friends 文档和/或Users 文档。此外,还有一个与此问题无关的原因,我们将 friends 作为每个用户的子集合,但如果需要,我们将其更改为统一的根级 Friends 集合。
这种设置使得查询任何给定用户按时间顺序排序的帖子变得非常容易,只需查找owner 字段等于该用户的文档引用的Posts 文档。
尽管我们正在为 iOS、Android、和 web 构建此应用程序,但我在 iOS/Swift 中通过以下方式实现了这一点。
guard let uid = Auth.auth().currentUser?.uid else {
print("No UID")
return
}
let firestoreUserRef = firestore.collection("Users").document(uid)
firestorePostsQuery = firestore.collection("Posts").whereField("owner", isEqualTo: firestoreUserRef).order(by: "timestamp", descending: true).limit(to: 25)
我的问题是如何查询在用户的
friends子集合中包含owner值的Posts文档,按时间顺序排序。换句话说,如何获取属于用户朋友的帖子,按时间排序。
以现实世界为例,考虑 Twitter,其中给定用户的提要由所有具有所有者属性的推文填充,该所有者属性的值包含在用户的以下列表中,按时间顺序排序。
现在,我从the documentation 知道 Firestore 不支持逻辑 OR 查询,所以我不能将所有朋友链接在一起。即使我可以,但对于只有少数朋友的人来说,这似乎并不是一个最佳方法。
我能想到的唯一选择是为每个朋友创建一个单独的查询。然而,这有几个问题。第一个挑战是(以平滑的方式)呈现来自许多异步获取的结果。第二个是每次更新一个查询快照(即实时更新)时,如果不重新在客户端手动重新排序集合,我就无法将数据按时间顺序合并。
是否可以构建我所描述的查询,或者我将不得不采用这种不太理想的方法?这似乎是一个相当常见的查询用例,所以如果没有办法做到这一点,我会感到惊讶。
【问题讨论】:
-
您不能在单个查询中执行此操作。正如您已经发现的那样,您将不得不在某个地方进行迭代并进行多次查询以收集您需要的所有内容。
-
@DougStevenson 我担心可能是这种情况。任何拥有多个朋友的用户真的会很倒霉。我认为我根本无法走这条路,因为我必须一遍又一遍地进行大量的查询、排序和重新排序。我没有办法重组我的数据以使其更可行,是吗?
-
执行多个查询并不是真正的问题。最大的问题是您阅读的文件数量。这是限制因素。只要您阅读的文档不超过实际需要,就可以了。
-
@DougStevenson 即使有大量查询不是问题,它仍然会产生您提到的有关阅读文档数量的问题。如果我有 200 个查询,每个朋友一个,那么我需要阅读至少 200 个文档——实际上比这要多得多,以确保我能够按时间顺序显示。现在,当我只尝试显示最近的 10 个文档时,我正在获取数千个文档。这不是很有效。
-
如果您需要限制读取的文档数量,只能通过对 Firestore 中单个集合的单个查询来完成。 Firestore 并不是每项工作的最佳解决方案,因此请对可能满足您查询需求的其他替代方案持开放态度。
标签: firebase google-cloud-firestore