代码之家  ›  专栏  ›  技术社区  ›  eozzy

在集合集合中搜索组查询

  •  0
  • eozzy  · 技术社区  · 3 年前

    因此,我发现了这样一个答案,它允许将collectionGroup查询限制为特定文档: CollectionGroupQuery but limit search to subcollections under a particular document

    但是,我也想使用 where ,这需要一个索引。查询工作正常,但始终返回空快照:

    const cityRef = firebase.firestore().doc('cities/cityId');
    
    firebase.firestore().collectionGroup('attractions')
      .where('name', '>=', keywords),
      .where('name', '<=', keywords + '\uf8ff')
      .orderBy('name')
      .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);
      })
    
    0 回复  |  直到 3 年前
        1
  •  2
  •   Frank van Puffelen    3 年前

    这里的防火罩

    问题几乎可以肯定的是,您的查询对两个不同的字段进行了范围检查( name 以及文档路径),这在Firestore的查询模型中是不可能的。作为上的文档 query limitations says :

    在复合查询中,范围(<,<=,>,>!=)和不等于(!=,not In)的比较都必须在同一字段上进行筛选。

    你的 startAt endAt 从句只是不同的写作方式 > < 就这一限制而言。

    为了理解为什么SDK允许你编写这个查询,但没有给你想要的结果,我们必须深入研究一下,所以。。。


    什么 可能的,是将所有相关字段传递给 startAt endAt 从而它可以在所有这些字段值上确定正确的切片。

    这样做甚至可以消除 where ,所以应该是:

    firebase.firestore().collectionGroup('attractions')
      .orderBy('name')
      .orderBy(firebase.firestore.FieldPath.documentId())
      .startAt(keywords, cityRef.path),
      .endAt(keywords + '\uf8ff', cityRef.path + "\uf8ff")
      .get()
      ...
    

    但此查询现在首先查找起始于 keywords 然后如果需要 cityRef.path 在那里消除多个结果之间的歧义。

    您想要的是与此查询等效的内容:

    const docId = firebase.firestore.FieldPath.documentId()l
    firebase.firestore().collectionGroup('attractions')
      .orderBy('name')
      .where('name', '>=', keywords),
      .where('name', '<=', keywords + '\uf8ff')
      .orderBy(firebase.firestore.FieldPath.documentId())
      .where(docId, '>=', cityRef.path),
      .where(docId, '<=', cityRef.path + '\uf8ff')
    

    现在很清楚为什么这是不可能的,因为我们有两个字段的范围条件。

    我一直试图在这个jsbin中实现这一点( https://jsbin.com/yiyifin/edit?js,console ),到目前为止还没有成功,但如果我能让它发挥作用,或者对它为什么不起作用有最终的判断,我会回来的。