【问题标题】:CollectionGroupQuery but limit search to subcollections under a particular documentCollectionGroupQuery,但将搜索限制在特定文档下的子集合
【发布时间】:2021-06-19 18:05:09
【问题描述】:

这是我的数据库结构。
城市 -> 地标 -> 景点(每一个都是一个集合)

查询
列出特定城市下的所有景点。

解决方案
在每个景点文档中保存 city_id
使用基于 city_id 的集合组查询和过滤器来获取特定城市的景点。

我的问题
除了在每个景点文档中保存 city_id 之外,我可以只将文档指定给 collectionGroupQuery,它现在只在此特定文档下的子集合中搜索。

在上面的例子中,我指定了城市文档的完整路径,我应该能够在不基于 city_id 过滤的情况下列出所有景点。

【问题讨论】:

    标签: firebase google-cloud-firestore


    【解决方案1】:
    推荐的答案 Google Cloud

    这应该可以使用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);
      })
    

    编辑:虽然上面的代码可以运行if the SDK allowed it,但由于额外的/,它目前会抛出一个关于有奇数段的错误。

    目前,只要您的所有城市 ID 的长度相同(就像使用默认的 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" 的城市也在城市集合中,那么它的结果也会包含在内。

    【讨论】:

    • 有趣的方法!您是否有“对于集合组查询,此值是文档的路径”的来源,因为我认为我以前从未读过?
    • @FrankvanPuffelen 根据我的理解,这是一个独特性的问题。在单个集合中,可能只有一个文档具有给定 ID,但在多个集合中,许多文档可能共享一个 ID,因此它使用它们的路径来实现唯一性。 source of the JS SDK 有一些明确的错误处理来处理任何错误的输入。 @doug 引用了此行为 here。
    • 在该链接中,Doug 建议将文档 ID 明确存储在文档本身中。我认为我从未在文档 ID 上看到过前缀条件,更不用说在它可能包含的路径上(我认为我也从未见过该语句)。我现在正在尝试为此设置一个重现,因为(如果这确实可能,即使很复杂)它会使相当多的现有答案无效。
    • 每当人们问:我可以查询某个路径下的集合时,我给出的答案(因此其他人在此之后给出的答案)一直是“Firestore 目前无法做到这一点”。如果您的答案有效,那么这些答案将不正确。
    • 刚刚标记为“Google Cloud 推荐”。真的很好的答案!
    猜你喜欢
    • 2019-10-29
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 2016-10-26
    • 2023-03-05
    • 2023-03-12
    • 1970-01-01
    • 2020-08-25
    相关资源
    最近更新 更多