CollectionGroupQuery但将搜索限制为特定文档下的子集合
这是我的数据库结构。
城市 -> 地标 -> 景点(每一个都是一个集合)
查询
列出特定城市下的所有景点。
解决方案
在每个景点文档中保存 city_id
使用基于 city_id 的集合组查询和过滤器来获取特定城市的景点。
我的问题
不是在每个景点文档中保存 city_id,我可以只将文档指定给 collectionGroupQuery,它现在只在这个特定文档下的子集合中搜索。
在上面的例子中,我指定了城市文档的完整路径,我应该能够列出所有景点而无需基于 city_id 进行过滤。
回答
这应该使用FieldPath.documentId().
每个文档__name__在其数据中都有一个隐藏字段,这是FieldPath.documentId().
对于普通的集合查询,它FieldPath.documentId()只是文档的 ID。但是,对于集合组查询,此值是文档的路径。
我们应该能够使用它来查找以给定城市的文档路径开头的所有匹配文档路径,如下所示:
const cityRef = firebase.firestore().doc('cities/cityId');
firebase.firestore().collectionGroup('attractions')
.orderBy(firebase.firestore.FieldPath.documentId())
.startAt(cityRef.path + "/"),
.endAt(cityRef.path + "/uf8ff")
.get()
.then((querySnapshot) => {
console.log("Found " + querySnapshot.size + " docs");
querySnapshot.forEach((doc) => console.log("> " + doc.ref.path))
})
.catch((err) => {
console.error("Failed to execute query", err);
})
编辑:虽然上面的代码在 SDK 允许的情况下会起作用,但由于额外的/.
目前,只要您所有的城市 ID 的长度相同(就像使用 default 一样docRef.add()),下面的代码就会起作用:
const cityRef = firebase.firestore().doc('cities/cityId');
firebase.firestore().collectionGroup('attractions')
.orderBy(firebase.firestore.FieldPath.documentId())
.startAt(cityRef.path),
.endAt(cityRef.path + "uf8ff")
.get()
.then((querySnapshot) => {
console.log("Found " + querySnapshot.size + " docs");
querySnapshot.forEach((doc) => console.log("> " + doc.ref.path))
})
.catch((err) => {
console.error("Failed to execute query", err);
})
上述块失败的地方是文档 ID 是否具有不同的长度。假设您只想要 下的文档"/cities/New York",如果另一个被称为"New Yorkshire"城市的城市也在城市集合中,它也会包含它的结果。