【问题标题】:firestore.where() on two fields at oncefirestore.where() 同时在两个字段上
【发布时间】:2021-12-02 16:03:54
【问题描述】:

我有以下文档的 Firestore 集合:

[
  {
    start:       { geohash: 'u3qchtmpuy2d' },
    destination: { geohash: 'u3qcjvxfh9cs' },
    timestamp:   '28 June 2019 at 20:24:00 UTC+2',
    ...
  }
]

我尝试像这样查询它(它的 Firestore Web SDK)

// 5-characters geohash is 4.89km × 4.89km
const start = 'u3qch';
const destination = 'u3qcj';
const timestamps = {
  min: firestore.Timestamp.fromDate(
    moment(someDateTime).subtract(10, 'minutes').toDate()
  ),
  max: firestore.Timestamp.fromDate(
    moment(someDateTime).add(10, 'minutes').toDate(),
  ),
};

firestore
  .collection('deliveries')
  .where('start.geohash', '>=', start)
  .where('start.geohash', '<', geohashEnd(start))
  .where('destination.geohash', '>=', destination)
  .where('destination.geohash', '<', geohashEnd(destination))
  .where('timestamp', '>=', timestamps.min)
  .where('timestamp', '<', timestamps.max)
  .get()

&gt;=&lt; 的组合来自Firestore: query documents by startsWith a string,因此是geoHashEnd() 函数(超出此问题的范围)。

导致以下错误:

FirebaseError:无效查询。具有不等式( 或 >=)的所有 where 过滤器必须位于同一字段中。但是您在“start.geohash”和“destination.geohash”上有不等式过滤器

我的问题:一次通过两个 geohash 字符串和一个附加字段查询我的 firestore 集合的最佳方法是什么?

【问题讨论】:

    标签: javascript node.js firebase google-cloud-firestore


    【解决方案1】:

    根据query limitations的官方文档:

    查询限制

    Cloud Firestore 不支持以下类型的查询:

    • 在不同字段上使用范围过滤器进行查询,如上一节所述。

    如您所见,Cloud Firestore 可以对单个字段进行范围过滤,而不能像您预期的那样对多个字段进行过滤。最合理的解释是 Firestore 在这种情况下无法保证其性能。 Firestore 必须能够在单个流中返回查询的所有结果。

    要解决这个问题,您必须查询数据库两次,并在客户端合并这些查询的结果。它并不完美,因为您需要查询两次,但我认为它可以解决问题。

    还请注意,在 geohashes 上使用范围过滤器进行查询不会返回非常准确的结果。为此,我建议您观看 Frank van Puffelen 关于该主题的精彩视频:

    【讨论】:

    • 是的,视频是我的起点,我也向邻居查询。你能为我的用例推荐任何数据库吗?
    • 要求我们推荐或查找书籍、工具、软件库、教程或其他场外资源的问题对于 Stack Overflow 来说是无关紧要的,因为它们往往会吸引固执己见的答案。
    • 恕我直言,我建议您继续查询数据库两次,它不会有问题。
    • 就我而言,不是两次,而是三次 - startdestinationtimestamp。我只对 20 分钟内的记录感兴趣 - 考虑一下我的应用程序已使用 4 年以上并且我仍然从同一地址查询所有旧记录的情况。
    • 哦,我明白了。就 Firestore 而言,甚至三次都不是问题。如果您对此不满意,我建议您首先只做一些测试,看看它是如何工作的。
    猜你喜欢
    • 2015-10-22
    • 1970-01-01
    • 2011-02-08
    • 2014-11-28
    • 2021-08-30
    • 2015-04-25
    • 2017-03-13
    相关资源
    最近更新 更多