在集合 collectionGroup 查询中搜索

Searching within collection collectionGroup query

所以我遇到了这个允许将 collectionGroup 查询限制为特定文档的答案:CollectionGroupQuery but limit search to subcollections under a particular document

但是我还想使用 where 根据特定字段进一步过滤结果,这需要索引。查询没有错误,但它总是 returns 空快照:

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);
  })

firebaser 在这里

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

In a compound query, range (<, <=, >, >=) and not equals (!=, not-in) comparisons must all filter on the same field.

就此限制而言,您的 startAtendAt 子句只是 >< 的不同写法。

要了解为什么 SDK 允许您编写此查询,但没有给您想要的结果,我们必须更深入地研究它,所以...


可能的,是将所有相关字段传递给startAtendAt,以便它可以确定所有这些字段值的正确切片.

这样做也将消除 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) 中工作,到目前为止没有成功,但如果我让它工作或有最终裁决,我会 post 回来为什么它不起作用。