CollectionGroupQuery 但将搜索限制为特定文档下的子集合 [英] CollectionGroupQuery but limit search to subcollections under a particular document
问题描述
这是我的数据库结构.
城市 ->地标 ->景点(每一个都是一个集合)
This is my database structure.
cities -> landmarks -> attractions(each one is a collection)
查询
列出特定城市下的所有景点.
Query
List all attractions under a particular city.
解决方案
在每个景点文档中保存city_id
使用集合组查询和基于 city_id 的过滤器来获取特定城市的景点.
Solution
Save city_id in each attraction document
Use a collection group query and filter based on city_id to get attractions of a particular city.
我的问题
不是在每个景点文档中保存city_id,我可以只将文档指定给collectionGroupQuery,它现在只在这个特定文档下的子集合中搜索.
My Question
Instead of saving city_id in each attraction document, can I just specify the document to the collectionGroupQuery which now only searches in subcollections under this particular document.
在上面的例子中,我指定了城市文档的完整路径,我应该能够列出所有景点而无需基于 city_id 过滤.
In the above example, I specify the city document's full path and i should be able to list all attractions without filtering based on city_id.
推荐答案
这应该可以使用 FieldPath.documentId()
.
This should work using FieldPath.documentId()
.
每个文档在其数据中都有一个隐藏的 __name__
字段,这是 FieldPath.documentId()
的目标.
Each document has a hidden __name__
field in its data and this is the target of FieldPath.documentId()
.
对于普通的集合查询,FieldPath.documentId()
只是文档的 ID.但是,对于集合组查询,此值是文档的路径.
For a normal collection query, FieldPath.documentId()
would just be the document's ID. However, for a collection group query, this value is the document's path.
我们应该能够使用它来查找以给定城市的文档路径开头的所有匹配文档路径,如下所示:
We should be able to use this to find all matching document paths that start with the given city's document path like so:
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 允许,由于额外的 /
,它当前会抛出关于具有奇数段的错误.
While the above code would function if the SDK allowed it, it currently throws an error about having an odd number of segments because of the extra /
.
目前,只要您所有的城市 ID 的长度相同(就像使用默认的 docRef.add()
一样),下面的代码就会起作用:
For now, as long as all your city IDs are the same length (as they would be if using the default docRef.add()
), the below code would function:
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"
的城市也在城市集合中,它会是结果也包括在内.
Where the above block fails is if the document ID have different lengths. Let's say you only wanted documents under "/cities/New York"
, if another city called "New Yorkshire"
was also in the cities collection, it would have it's results included too.
这篇关于CollectionGroupQuery 但将搜索限制为特定文档下的子集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!