問題描述
經(jīng)過一些研究,很明顯我不能使用 FireStore 來查詢給定數(shù)組不包含的項(xiàng)目.有人對此用例有解決方法嗎?...
After some research, it's seems clear that I cannot use FireStore to query items a given array does NOT contain. Does anyone have a workaround for this use case?...
用戶注冊后,應(yīng)用會獲取一堆卡片,每張卡片在 FireStore 中都有對應(yīng)的卡片"文檔.用戶與卡片交互后,卡片文檔將用戶的 uid 添加到字段數(shù)組(例如:usersWhoHaveSeenThisCard:[userUID]),用戶"文檔將卡片的 uid 添加到字段數(shù)組(例如:cardThisUserHasSeen:[cardUID]).用戶"文檔存在于用戶"集合中,卡片"文檔存在于卡片"集合中.
After a user signs up, the app fetches a bunch of cards that each have a corresponding "card" document in FireStore. After a user interacts with a card, the card document adds the user's uid to a field array (ex: usersWhoHaveSeenThisCard: [userUID]) and the "user" document adds the card's uid to a field array (ex: cardsThisUserHasSeen: [cardUID]). The "user" documents live in a "user" collection and the "card" documents live in a "card" collection.
目前,我想獲取用戶未與之交互的所有卡片.但是,這是有問題的,因?yàn)槲抑恢烙脩襞c之交互的卡片,因此 .whereField(usersWhoHaveSeenThisCard, arrayContains: currentUserUID) 將不起作用,因?yàn)槲倚枰粋€(gè)不存在的arrayDoesNotContain"語句.
Currently, I'd like to fetch all cards that a user has NOT interacted with. However, this is problematic, as I only know the cards that a user has interacted with, so a .whereField(usersWhoHaveSeenThisCard, arrayContains: currentUserUID) will not work, as I'd need an "arrayDoesNotContain" statement, which does not exist.
最后,用戶不能擁有卡片,因此我無法在卡片文檔中創(chuàng)建真/假布爾字段(例如:userHasSeenThisCard: false)并根據(jù)該條件進(jìn)行搜索.
Finally, a user cannot own a card, so I cannot create a true / false boolian field in the card document (ex: userHasSeenThisCard: false) and search on that criteria.
我能想到的唯一解決方案是在卡片文檔上創(chuàng)建一個(gè)新的字段數(shù)組,其中包括所有沒有看到卡片的用戶(例如:usersWhoHaveNotSeenThisCard: [userUID]),但這意味著每個(gè)用戶注冊必須將他們的 uid 寫入 1000 多個(gè)卡片文檔,這會占用我的數(shù)據(jù).
The only solution I can think of, would be to create a new field array on the card document that includes every user who has NOT seen a card (ex: usersWhoHaveNotSeenThisCard: [userUID]), but that means that every user who signs up would have to write their uid to 1000+ card documents, which would eat up my data.
我可能只是運(yùn)氣不好,但我希望對 NOSQL/FireStore 更了解的人可以提供一些見解.
I might just be out of luck, but am hoping someone more knowledgeable with NOSQL / FireStore could provide some insight.
// If any code sample would help, please let me know and I'll update - I think this is largely conceptual as of now
推薦答案
有一個(gè)公認(rèn)的很好的答案,但是,它不能直接解決這個(gè)問題,所以這里......(這可能會也可能不會有幫助,但確實(shí)有效)
There is an accepted and good answer, however, it doesn't provide a direct solution to the question so here goes... (this may or may not be helpful but it does work)
我不確切知道您的 Firestore 結(jié)構(gòu)是什么,所以這是我的假設(shè):
I don't know exactly what your Firestore structure is so here's my assumption:
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
假設(shè)我們想知道 uid_2 沒有看到哪些卡 - 在本例中是 card_id_2
Suppose we want to know which cards uid_2 has not seen - which in this case is 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)
})
}
那么,這樣的用例
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)")
}
})
}
和輸出
user: uid_2 has not seen: card_id_2
此代碼遍歷文檔,獲取存儲在每個(gè)文檔 usersWhoHaveSeenThisCard 節(jié)點(diǎn)中的 uid 數(shù)組,并確定 uid 是否在數(shù)組中.如果沒有,它會將 documentID 添加到 documentsIdsThatDoNotContainThisUser 數(shù)組中.檢查完所有文檔后,將返回不包含用戶 ID 的文檔 ID 數(shù)組.
This code goes through the documents, gets the array of uid's stored within each documents usersWhoHaveSeenThisCard node and determines if the uid is in the array. If not, it adds that documentID to the documentsIdsThatDoNotContainThisUser array. Once all docs have been checked, the array of documentID's that do not contain the user id is returned.
知道 Firestore 的速度有多快,我針對一個(gè)大型數(shù)據(jù)集運(yùn)行了代碼,結(jié)果很快就返回了,因此對于大多數(shù)用例來說它不會造成任何延遲.
Knowing how fast Firestore is, I ran the code against a large dataset and the results were returned very quickly so it should not cause any kind of lag for most use cases.
這篇關(guān)于FireStore - 如何繞過數(shù)組“不包含"查詢的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!