按缺失字段约束结果排序

Ste*_*ley 7 firebase google-cloud-firestore

我遇到了 Firestore 的一个问题,这对我来说很不直观,所以我想知道是否有人可以帮助我理解 Firestore 给出这个结果的原因。

假设我有一个名为“people”的集合,其中包含“firstName”和“lastName”字段。假设该集合中有 20 个文档的姓氏为“Quaid”。然后我有一个字段“inCanada”,它只出现在这 20 个文档的一个子集中,比方说 5 个。其他 15 个文档没有该字段。

令人惊讶的是,使用该可选字段的 orderBy 子句实际上是在过滤结果集,而不仅仅是对其进行排序,与其他数据库相比,这对我来说没有意义。

在下面的示例中,我希望两个结果集都有 20 个元素,但是具有 orderBy 的第二个集只有 5 个存在该字段的文档。

有人可以解释为什么 Firestore 这样做吗?

const Admin = require('firebase-admin');

(async function () {
  const initFirebase = require('../initFirebase');
  initFirebase();

  const people = Admin.firestore().collection('people');
  const quaids = people.where('lastName', '==', 'Quaid')
  const quaids1 = await quaids.get();
  const quaids2 = await quaids.orderBy('inCanada', 'desc').get();

  console.log(quaids1._size); // 20
  console.log(quaids2._size); // 5
})();
Run Code Online (Sandbox Code Playgroud)

Ren*_*nec 7

简而言之,这是因为 Firestore 查询基于索引:每次创建文档时,Firestore 都会为文档的每个字段创建一个索引。

因此,由于字段“inCanada”仅存在于“20 个文档的一个子集中”,因此“inCanada”索引中仅存在该文档子集,从而导致您提到的情况。

这个来自 Firebase 团队的 Todd Kerpelman 的官方视频很好地解释了它:https : //www.youtube.com/watch?v= Ofux_4c94FI#t=4m17s 。(这个链接会在4分17秒打开视频,也就是索引机制的讲解开始的时候。但是关于索引对查询可能性的影响的部分更多的是6分22秒左右!)

如果您想在查询结果中包含其他文档,您应该为这些文档的“inCanada”字段写入一个值,例如使用一个false值(并true用于“inCanada”的文档)。

  • 这在无模式数据库中尤其尴尬,因为您不能依赖集合的所有对象上的给定字段的存在。我已经为 Firebase 支持填充了一个错误。 (3认同)
  • 我从 firebase 支持那里得到了一个答案:由于查询使用索引的方式,目前确实不支持,但他们为此创建了一个功能请求。所以这可能会在未来得到支持。 (3认同)
  • 是的,我知道索引是如何工作的,我的问题更多的是为什么而不是如何。让 orderBy 影响没有指定任何限制的结果集的大小,这似乎是一个非常尴尬的设计决策。不管怎样,谢谢你的回答。 (2认同)