如果我有一个简单的集合,如:
Fruits:
Banana:
title: "Banana"
vitamins: ["potassium","B6","C"]
Apple:
title: "Apple"
vitamins: ["A","B6","C"]如果我想搜索含有维生素B6的水果,我会做以下几件事:
db.collection("Fruits").whereField("vitamins", arrayContains: "A").getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
print("\(document.documentID) => \(document.data())")
}
}
}这将向我展示我收藏中含有维生素A的所有水果,然而,我如何才能找到含有多种维生素的水果,比如维生素B6和C?我不能简单地搜索["B6","C"],因为它将寻找一个数组,而不是独立的字符串。
这在中是可能的吗?若否,是否有其他方法可供选择?
发布于 2019-03-04 16:50:35
通过将查询中的条件链接起来,寻找匹配多个条件的文档是很有诱惑力的:
db.collection("Fruits")
.whereField("vitamins", arrayContains: "B6")
.whereField("vitamins", arrayContains: "C")但是,关于复合查询的文档建议您当前不能在一个查询中有多个arrayContains条件。
所以,你今天所拥有的是不可能的。考虑使用映射结构而不是数组:
Fruits:
Banana:
title: "Banana"
vitamins: {
"potassium": true,
"B6": true,
"C": true
}然后您可以这样查询:
db.collection("Fruits")
.whereField("vitamins.B6", isEqualTo: true)
.whereField("vitamins.C", isEqualTo: true)发布于 2020-05-04 14:12:43
Firestore在2019年末引入了whereIn、arrayContains和arrayContainsAny方法。这些方法执行逻辑的“OR”查询,但是您可以传递10个子句(所以最多可以搜索10种维生素)。
有些解决方案已经提到重组您的数据。另一种利用重组方法的解决方案是不将维生素纳入果树文档,而是相反。这样你就可以得到所有的文件‘香蕉’是。
let vitaminsRef = db.collection('Vitamins').where('fruits', arrayContains: 'banana');此解决方案允许您规避10条的限制。它会在一次读取操作中获得“香蕉”数组中包含“香蕉”的所有“维生素”文档(如果太多的话,请考虑分页)。
发布于 2019-03-04 16:53:13
在Firestore中无法执行多个数组-包含查询。但是,您可以结合尽可能多的where条件。因此,请考虑这一点:
[Fruits]
<Banana>
title: "Banana"
vitamins:
potassium: true
b6: true
c: true
Firestore.firestore().collection("Fruits").whereField("vitamins.potassium", isEqualTo: true).whereField("vitamins.b6", isEqualTo: true)然而,这仍然不允许一个干净的OR搜索。要想查询含有维生素x或维生素Y的水果,你必须要有更多的创造力。此外,如果存在大量可能的值,并且需要将它们与复合查询结合起来,则不应该使用这种方法。这是因为Firestore不允许超过200个复合指数,而且每个复合指数都需要指定确切的维生素。这意味着您必须为vitamins.b6、vitamins.potassium等创建一个单独的复合索引,总共只有200个。
https://stackoverflow.com/questions/54987399
复制相似问题