如何继续向现有 Firestore 查询添加条件?
Posted
技术标签:
【中文标题】如何继续向现有 Firestore 查询添加条件?【英文标题】:How to keep adding conditions to an existing Firestore query? 【发布时间】:2021-07-29 21:56:48 【问题描述】:在没有应用任何过滤器的情况下,我正在像这样查询我的 Firestore 数据库:
var query:Query = db.collection("myFirestoreData")
queryData()
我的应用还有 4 个用于过滤的按钮。
例如,如果点击“便宜”,这就是我过滤 isCheap = true
的数据的方式:
if cheapOnly == true
query = query
.whereField("isCheap", isEqualTo: true)
如果有人也点按“简单”,我该如何应用两个过滤器(即过滤isCheap = true
和isEasy = true
的数据?我想我可以像这样在query
引用中添加另一个whereField
条件:
if cheapOnly == true
query = query
.whereField("isCheap", isEqualTo: true)
if easyOnly == true
query = query
.whereField("isEasy", isEqualTo: true)
当两个按钮都被点击时,上面的所有代码都会运行,但我继续只获得一个或另一个过滤。我该怎么做:
-
在另一个之上应用查询条件(即,通过 既 简单和便宜的过滤条件)?以及
过滤器的点击顺序是否无关紧要(即,无论是先点击还是第二点击 Easy 或 Cheap,结果都相同)?
非常感谢任何支持/指导!
编辑:
在下面添加了我的数据模型的完整代码,看看是否有人可以在那里发现不正确的地方。
class MealPlanModel
var delegate:MealPlanProtocol?
var listener:ListenerRegistration?
var mealPlan = [MealPlan]()
func getMealPlans(starred starredOnly:Bool = false, textToQuery searchText:String = "", easyFiltered easyOnly:Bool = false, cheapFiltered cheapOnly:Bool = false, highProteinFiltered highProteinOnly:Bool = false, vegetarianFiltered vegetarianOnly:Bool = false)
// Detach any listener
listener?.remove()
// Get a reference to the database
let db = Firestore.firestore()
var query:Query = db.collection("mealPlans")
if cheapOnly == true
query = query
.whereField("isCheap", isEqualTo: true)
if easyOnly == true
query = query
.whereField("isEasy", isEqualTo: true)
func queryData()
self.listener = query.addSnapshotListener( (snapshot, error) in
// Check for errors
if error == nil && snapshot != nil
var mealPlans = [MealPlan]()
// Parse documents into mealPlans
for doc in snapshot!.documents
let m = MealPlan(
docID: doc["docID"] as? String,
title: doc["title"] as? String)
mealPlans.append(m)
DispatchQueue.main.async
self.delegate?.mealPlansRetrieved(mealPlans: mealPlans)
)
queryData()
【问题讨论】:
您在问题中分享的代码乍一看还不错。如果您可以显示一个重现问题的 sn-p,可能会更容易提供帮助。 谢谢@FrankvanPuffelen!我在我的数据模型中添加了其余代码。你发现那里有什么不正确的地方吗?我想知道我是否可能在错误的地方调用queryData()
,因此查询在我的if
语句之间重置。
你能在queryData
函数中打印running query data with isEasy and isCheap
吗?所以我们知道函数正在运行并且 isEasy 和 isCheap 的值都是 true?
【参考方案1】:
那么,根据我的理解,您希望允许多个真实条件,仅在选中时?我做了一些非常相似的事情,很有趣,一个像你这样的食物应用程序。这只是关于“操纵”对数据库的引用,如下所示:
var ref = db.collection("myFirestoreData")
if cheapOnly
ref = ref.whereField("isCheap", isEqualTo: true)
if easyOnly
ref = ref.whereField("isEasy", isEqualTo: true)
ref.limit(to: 20).getDocuments
//Get your documents
这是基于您传递选项值的假设,即便宜、简单等。
【讨论】:
非常感谢这个例子!在我看来,我的结构与您的结构相似。我在我的数据模型中发布了其余的相关代码。你觉得里面有什么不对吗?是不是我打错了queryData()
?
@amirbt17 你为什么要使用监听器?侦听器实际上应该只用于来自 Firebase 的更新,使用侦听器可能会变得非常昂贵。您只是想获取您的参考,查询您认为合适的方式并使用.getDocuments
。在您的 getDocuments
闭包中,您可以转换数据等。【参考方案2】:
以下工作:
if easyOnly == true || cheapOnly == true || highProteinOnly == true || vegetarianOnly == true
// Reset the query
db.collection("mealPlans").document().getDocument (snapshot, error) in
self.query = db.collection("mealPlans")
// Refine the query based on the button taps
if easyOnly == true
self.query = self.query
.whereField("isEasy", isEqualTo: true)
if cheapOnly == true
self.query = self.query
.whereField("isCheap", isEqualTo: true)
if highProteinOnly == true
self.query = self.query
.whereField("isHighProtein", isEqualTo: true)
if vegetarianOnly == true
self.query = self.query
.whereField("isVegetarian", isEqualTo: true)
queryData()
else
db.collection("mealPlans").document().getDocument (snapshot, error) in
self.query = db.collection("mealPlans")
queryData()
self.query = db.collection("mealPlans")
在按下多个按钮时帮助重置查询。
queryData()
在每个查询结束时实现,以便在设置所有.whereField
参数后提交查询。
【讨论】:
以上是关于如何继续向现有 Firestore 查询添加条件?的主要内容,如果未能解决你的问题,请参考以下文章