Luc*_*rdi 8 firebase swift google-cloud-firestore
如果我有一个简单的集合,例如:
Fruits:
Banana:
title: "Banana"
vitamins: ["potassium","B6","C"]
Apple:
title: "Apple"
vitamins: ["A","B6","C"]
Run Code Online (Sandbox Code Playgroud)
如果我要搜索含有维生素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())")
}
}
}
Run Code Online (Sandbox Code Playgroud)
这样一来,我便可以看到我收藏的所有含有维生素A的水果。但是,我如何能够搜索含有多种维生素(例如维生素B6和C)的水果?我不能简单地搜索["B6","C"],因为那样会寻找数组,而不是独立的字符串。
在Cloud Firestore中甚至有可能吗?如果没有,还有其他替代方法吗?
Dou*_*son 11
It would be tempting to to look for documents that match multiple conditions, by chaining the conditions in the query:
db.collection("Fruits")
.whereField("vitamins", arrayContains: "B6")
.whereField("vitamins", arrayContains: "C")
Run Code Online (Sandbox Code Playgroud)
But the documentation on compound queries suggests that you cannot currently have multiple arrayContains conditions in a single query.
So, it is not possible with what you have today. Consider instead using a map structure instead of an array:
Fruits:
Banana:
title: "Banana"
vitamins: {
"potassium": true,
"B6": true,
"C": true
}
Run Code Online (Sandbox Code Playgroud)
Then you could query like this:
db.collection("Fruits")
.whereField("vitamins.B6", isEqualTo: true)
.whereField("vitamins.C", isEqualTo: true)
Run Code Online (Sandbox Code Playgroud)
无法在 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)
Run Code Online (Sandbox Code Playgroud)
然而,这仍然不允许进行干净的OR搜索。要查询含有维生素 X 或维生素 Y 的水果,您必须发挥更多创意。此外,如果有很多可能的值并且需要将它们与复合查询结合起来,则不应使用此方法。这是因为 Firestore 不允许超过 200 个复合索引,并且每个复合索引都需要指定确切的维生素。这意味着您必须为vitamins.b6、vitamins.potassium等创建单独的复合索引,而总共只有 200 个。
Firestore 在 2019 年末引入了 whereIn、arrayContains 和 arrayContainsAny 方法。这些方法执行逻辑“或”查询,但您可以传入的子句限制为 10 个(因此您最多可以搜索 10 个维生素)。
一些解决方案已经提到重组您的数据。利用重组方法的另一个解决方案是不将维生素包含在 Fruit 文档中,而是反过来。通过这种方式,您可以获得“香蕉”所属的所有文件。
let vitaminsRef = db.collection('Vitamins').where('fruits', arrayContains: 'banana');
Run Code Online (Sandbox Code Playgroud)
此解决方案允许您绕过 10 个子句的限制。它在一次读取操作中获取所有在“水果”数组中包含“香蕉”的“维生素”文档(考虑分页,如果太多的话)。
| 归档时间: |
|
| 查看次数: |
6797 次 |
| 最近记录: |