bhe*_*h90 5 database nosql firebase swift google-cloud-firestore
经过一些研究,很明显我不能使用 FireStore 来查询给定数组不包含的项目。有没有人对此用例有解决方法?...
用户注册后,应用程序会获取一堆卡片,每张卡片在 FireStore 中都有一个对应的“卡片”文档。用户与卡片交互后,卡片文档将用户的 uid 添加到字段数组中(例如:usersWhoHaveSeenThisCard: [userUID]),“user”文档将卡片的 uid 添加到字段数组中(例如:cardsThisUserHasSeen: [cardUID]) )。“user”文档位于“user”集合中,“card”文档位于“card”集合中。
目前,我想获取用户未与之交互的所有卡片。但是,这是有问题的,因为我只知道用户与之交互的卡片,因此 .whereField(usersWhoHaveSeenThisCard, arrayContains: currentUserUID) 将不起作用,因为我需要一个不存在的“arrayDoesNotContain”语句。
最后,用户不能拥有卡片,因此我无法在卡片文档中创建真/假布尔字段(例如:userHasSeenThisCard:false)并根据该条件进行搜索。
我能想到的唯一解决方案是在卡片文档上创建一个新的字段数组,其中包含所有没有看过卡片的用户(例如:usersWhoHaveNotSeenThisCard:[userUID]),但这意味着每个注册的用户都会必须将他们的 uid 写入 1000 多个卡文件,这会吃掉我的数据。
我可能只是不走运,但我希望更了解 NOSQL/FireStore 的人可以提供一些见解。
// If any code sample would help, please let me know and I'll update - I think this is largely conceptual as of now
Run Code Online (Sandbox Code Playgroud)
有一个公认的良好答案,但是,它没有提供问题的直接解决方案,所以这里...(这可能有帮助,也可能没有帮助,但它确实有效)
我不知道你的 Firestore 结构到底是什么,所以这是我的假设:
cards
card_id_0
usersWhoHaveSeenThisCard
0: uid_0
1: uid_1
2: uid_2
card_id_1
usersWhoHaveSeenThisCard
0: uid_2
1: uid_3
card_id_2
usersWhoHaveSeenThisCard
0: uid_1
1: uid_3
Run Code Online (Sandbox Code Playgroud)
假设我们想知道哪些卡 uid_2 没有见过 - 在本例中是 card_id_2
func findCardsUserHasNotSeen(uidToCheck: String, completion: @escaping ( ([String]) -> Void ) ) {
let ref = self.db.collection("cards")
ref.getDocuments(completion: { snapshot, err in
if let err = err {
print(err.localizedDescription)
return
}
guard let docs = snapshot?.documents else {
print("no docs")
return
}
var documentsIdsThatDoNotContainThisUser = [String]()
for doc in docs {
let uidArray = doc.get("usersWhoHaveSeenThisCard") as! [String]
let x = uidArray.contains(uidToCheck)
if x == false {
documentsIdsThatDoNotContainThisUser.append(doc.documentID)
}
}
completion(documentsIdsThatDoNotContainThisUser)
})
}
Run Code Online (Sandbox Code Playgroud)
然后,用例是这样的
func checkUserAction() {
let uid = "uid_2" //the user id to check
self.findCardsUserHasNotSeen(uidToCheck: uid, completion: { result in
if result.count == 0 {
print("user: \(uid) has seen all cards")
return
}
for docId in result {
print("user: \(uid) has not seen: \(docId)")
}
})
}
Run Code Online (Sandbox Code Playgroud)
和输出
user: uid_2 has not seen: card_id_2
Run Code Online (Sandbox Code Playgroud)
此代码遍历文档,获取存储在每个文档的 usersWhoHaveSeenThisCard 节点中的 uid 数组,并确定 uid 是否在数组中。如果没有,它会将该 documentID 添加到 DocumentsIdsThatDoNotContainThisUser 数组中。检查完所有文档后,将返回不包含用户 ID 的 documentID 数组。
知道 Firestore 的速度有多快后,我针对大型数据集运行了代码,并且结果返回得非常快,因此对于大多数用例来说,它不会造成任何类型的延迟。
| 归档时间: |
|
| 查看次数: |
2377 次 |
| 最近记录: |