如何让 Firestore 索引合并工作?

Aur*_*zeb 5 indexing firebase google-cloud-firestore

我在使用 Firestore 索引合并以减少所需索引的数量时遇到了问题。

考虑以下示例情况:

Firestore 集合:测试/somedoc

{
  a: '1',
  b: '1',
  c: '1',
  d: '1'
}
Run Code Online (Sandbox Code Playgroud)

这将导致 Firestore 在测试字段 a 到 d 时创建 4 个自动单字段索引。

使用几个相等条件和一个不相关的排序查询此表:

    await db.collection('test')
        .where('a', '==', '1')
        .where('b', '==', '1')
        .where('c', '==', '1')
        .orderBy('d')
        .get();
Run Code Online (Sandbox Code Playgroud)

这会导致 Firebase 失败并提示创建包含所有字段的复合索引。这是预期的。

现在根据文档(https://firebase.google.com/docs/firestore/query-data/index-overview#taking_advantage_of_index_merging),如果您已经在例如字段 c 和 d 上有一个复合,firestore 将使用索引合并要求所有字段的复合索引。

消防索引

但是,如果您在集合测试上创建索引,例如使用 c asc、d asc,查询仍然会失败并提示创建完整的复合索引。

UnhandledPromiseRejectionWarning: FirebaseError: The query requires an index. 
Run Code Online (Sandbox Code Playgroud)

我在这里做错了什么?

Aur*_*zeb 5

好吧终于明白了这里的问题。

为了使索引合并正常工作,您需要覆盖所有相关字段的复合索引。自动生成的单字段索引不会用于合并。

因此,如果您创建两个附加的复合索引

  • 上升,上升
  • b 上升,d 上升

那么所有字段将被覆盖并自动使用索引合并。


Sam*_*ern 5

@Aurangzeb 有正确的答案,但我想详细说明

因此,如果您想在该查询上使用索引合并,则确实需要 3 个复合索引(a, d)(b, d)(c, d)

然而,在某些情况下使用单个(a, b, c, d)索引仍然会更快,无论如何您都应该考虑添加它。如果 3 个索引的结果集大小相差很大,则索引合并速度会较慢。考虑您的查询:

collection
  .where(a == 1)
  .where(b == 1)
  .where(c == 1)
  .orderBy(d)
Run Code Online (Sandbox Code Playgroud)

假设您拥有一百万个文档的集合,其中 50% 具有a == 1b == 1但只有 0.1% 具有c == 1. 在这种情况下,在索引消除大部分结果之前,从索引读取(a, d)实际上做了相当多的浪费工作。(c, d)单个(a, b, c, d)索引所做的工作可能最少。这就是为什么 Firebase SDK 和控制台总是建议最准确的索引,即使有一种方法可以使用合并索引来满足查询。