【问题标题】:How to create firestore dynamic queries correctly如何正确创建 Firestore 动态查询
【发布时间】:2021-01-10 05:04:36
【问题描述】:

我正在尝试使用这种方法为 Firestore 构建动态查询:Cloud Firestore - Dynamic Querying

这是我构建查询的方式:

buildQueryRef(ref: firebase.firestore.CollectionReference, queryMap: ProductQueryMap, lastDoc?: Item) {

    var query : Query = ref; 
    
    if (queryMap.minPrice)
      query = query.where("price", ">=", queryMap.minPrice) || ref.where("price", ">=", queryMap.minPrice);

    if (queryMap.maxPrice)
      query = query.where("price", "<=", queryMap.maxPrice) || ref.where("price", "<=", queryMap.maxPrice);

    if (queryMap.type)
      query = query.where("type", "==", queryMap.type) || ref.where("type", "==", queryMap.type);

    if (queryMap.orType)
      query = query.where("type", "in", queryMap.type) || ref.where("type", "in", queryMap.type);

    if (queryMap.status)
      query = query.where("status", "in", queryMap.status) || ref.where("status", "in", queryMap.status);

    if (queryMap.keywords || queryMap.orKeywords)
      query = query.where("keywords", "array-contains-any", queryMap.keywords) || ref.where("keywords", "array-contains-any", queryMap.keywords);

    if (queryMap.userId) {
      query = query.where("userId", "==", queryMap.userId) || ref.where("userId", "==", queryMap.userId);
      // query.orderBy("userId", "desc");
      // orderArr.push("userId");
    }
    if (queryMap.minPrice || queryMap.maxPrice)
      query = query.orderBy("price", "asc") || ref.orderBy("price", "asc");

    query = query.orderBy("created", "desc") || ref.orderBy("created", "desc");

    if (lastDoc)

      query = query.startAfter(lastDoc.created) || ref.startAfter(lastDoc.created);

    query = query.limit(12) || ref.limit(12);
    return query;
  }

因此,例如,如果我进行一个没有参数的查询,它只会设置 orderBy("created", "desc") 和 limit(12) 并且会正常工作,但只要它收到任何其他参数,如 userId 或 type 它不返回任何文档。

起初有一条错误消息,其中包含在 Firestore 中创建复合索引的链接,但后来我按照建议创建了索引,然后它没有返回任何文档。

我想知道是否可以使用这种方法进行查询,因为为每个可能的参数组合编写查询是不切实际的。

提前致谢。

【问题讨论】:

  • 这不是必需的:query = query.where("price", "&gt;=", queryMap.minPrice) || ref.where("price", "&gt;=", queryMap.minPrice);。相反,您可以只做query = query.where("price", "&gt;=", queryMap.minPrice);

标签: angular typescript google-cloud-firestore angularfire2


【解决方案1】:

Firestore 要求在成功进行查询之前必须存在索引。如何创建它们取决于您,但这不是可选步骤。如果您要应用许多排序和过滤器组合,则必须像以前一样手动创建它们,或者找到某种方法来自动化。

您可能会发现对generate a JSON descriptiondeploy with the Firebase CLIinvoke the REST API directly 的索引很有帮助。无论哪种方式,这都不是微不足道的工作。

【讨论】:

  • 你好@Doug Stevenson。正如您所提到的,我创建了一对索引,一个用于查询 userId 的项目,一个用于查询类型,因为 firestore 需要这样的索引。问题是它们似乎都不起作用。例如,当我进行这样的查询时:this.fs.collection("products", ref =&gt; ref.where("userId", "==", userId).orderBy("created", "desc").startAfter(lastDoc.created).limit(12)).valueChanges().subscribe(resolve, reject); 工作正常,但以其他方式构建则不会
  • 如果您的查询没有返回任何文档,这不是索引的问题。这只是没有匹配文件的结果。缺少适当的索引总是会导致错误。 Firestore 不会在没有查询的情况下执行查询。
  • 如果没有匹配的文档,“静态”查询也会返回 0 个文档,这是我不明白的,但我想我将不得不找出另一个解决方案。还是谢谢。
猜你喜欢
  • 2018-05-05
  • 2019-04-08
  • 1970-01-01
  • 2012-02-09
  • 2018-10-27
  • 1970-01-01
  • 1970-01-01
  • 2017-04-20
  • 1970-01-01
相关资源
最近更新 更多