为什么Firestore无法在不同字段上执行具有不等式条件的查询?

时间:2020-06-14 17:57:53

标签: firebase google-cloud-firestore

我在Firestore数据库中非常陌生,并且以前没有使用NoSql数据库的经验(我来自经典的关系数据库)

我知道我可以执行以下查询:

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

应该检索所有对象(从我的courses集合中,其中seqNo字段等于5,并且lessonCount字段的值为{{1} }。

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

我不了解的是为什么在Firebase中无法实现一些简单而自然的查询。例如,经典范围查询,将上一个查询更改为以下内容:我想检索所有具有>=5seqNo >= 5的课程:

lessonCount >= 5

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

但是我不明白为什么Firestore无法在不平等条件没有不同过滤条件的情况下执行查询

为什么?它是如何工作的?我想念什么?

2 个答案:

答案 0 :(得分:2)

我确定有人会提供比我更全面的解释,但我是这样想的。 Firestore保证查询将在O(n)时间内执行,其中n是查询中匹配的文档数。换句话说,查询根据所请求的文档数量进行缩放。 Firestore旨在在大规模(考虑集合中的数十亿文档)的所有(或几乎所有)情况下实现这一目标。只要您有支持查询的索引,该查询就会几乎总是运行良好,并且您不必担心扩展或分片。就是这样。

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

这并不是说Firestore根本无法做到这一点,但这会大大增加问题的严重性。如果它提供了多个范围查询,我希望您为实现这一目标而付出相当高的代价,而您将再也无法获得其原始性能保证。

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

限制为单个范围查询的好处是性能永远不会大规模降低。缺点是您无法做所有想做的事。如果您需要一些想法,可以在堆栈溢出中讨论很多解决方法。

答案 1 :(得分:0)

自2020年10月起,尽管有一定的局限性,但已经实施了不平等的救火措施。 Cloud Firestore now supports not equal queries