【问题标题】:Why Firestore can't perform query having inequality conditions on different fields?为什么 Firestore 无法在不同字段上执行具有不等式条件的查询?
【发布时间】:2020-06-14 17:57:53
【问题描述】:

我是 Firestore 数据库的新手,之前没有使用 NoSql 数据库的经验(我来自经典关系数据库)

我知道我可以执行这样的查询:

return this.db.collection(
      'courses',
        ref=>ref.where("seqNo", "==", "5")
                .where("lessonCount", ">=", 5)

这应该检索所有对象(来自我的courses 集合),其中seqNo 字段等于5 并且lessonCount 字段具有值>=5

好的,这个查询可以正常工作。

我不明白的是,为什么在 Firebase 中无法实现一些简单且非常自然的查询。例如一个经典的范围查询,改变以前的查询是这样的:我想检索所有具有seqNo >= 5lessonCount >= 5的课程:

return this.db.collection(
      'courses',
        ref=>ref.where("seqNo", ">=", "5")
                .where("lessonCount", ">=", 5)

我知道这是与性能和索引相关的权衡。

但我不明白为什么 Firestore 不能在不等式条件没有不同过滤器的情况下执行查询

为什么?它是如何在引擎盖下工作的?我错过了什么?

【问题讨论】:

    标签: firebase google-cloud-firestore


    【解决方案1】:

    我相信有人比我有更全面的解释,但我是这样想的。 Firestore 保证查询在 O(n) 时间内执行,其中 n 是查询中匹配文档的数量。换句话说,查询根据请求的文档数量进行扩展。 Firestore 旨在在所有(或几乎所有)情况下以及在大规模(想想一个集合中的数十亿个文档)中实现这一点。只要您有支持查询的索引,查询将几乎总是表现良好,您无需担心缩放或分片。它只是工作。

    当您对字段使用范围查询时,需要对该字段使用升序或降序索引。索引知道集合中所有文档相对于该字段的顺序,并且它可以使用该索引有效地找到要匹配的可能文档的范围。 但是,当您在另一个字段上引入第二个范围时,这将需要一个完全不同的索引和一个完全不同的潜在范围匹配。 这些范围无法合并,在 Firestore 的大规模范围内,仍然可以提供上述性能保证。它必须加载可以匹配任一范围的整套文档到内存(或一些临时存储),找到两者之间的重叠,然后对其应用任何其他过滤器。想一想 - Firestore 出于性能原因根本不愿意将数十亿个文档加载到内存中以查找范围重叠。

    并不是说 Firestore 不能做到这一点,但这会大大增加问题的严重性。如果它提供多个范围查询,我希望您会为实现这一目标的计算资源付出高昂的代价,并且您将无法再获得其最初的性能保证。

    为了更灵活的查询,您可以将数据镜像到BigQuery(甚至还有一个extension),这可能会为您提供尽可能多的灵活性。只是不要期望您的查询会很快,并准备好支付 BigQuery 数据仓库功能的费用。

    限制为单个范围查询的好处是性能永远不会大规模降低。缺点是你不能做你想做的一切。如果您想了解一些想法,可以在 Stack Overflow 上讨论很多解决方法。

    【讨论】:

      【解决方案2】:

      自 2020 年 10 月起,Firestore 已实施不平等,但存在一些限制。 Cloud Firestore now supports not equal queries

      【讨论】:

        猜你喜欢
        • 2021-10-21
        • 2021-04-09
        • 2020-11-21
        • 1970-01-01
        • 2021-07-09
        • 1970-01-01
        • 2020-01-07
        • 2020-01-16
        • 1970-01-01
        相关资源
        最近更新 更多