【问题标题】:Firebase Firestore Query Between Two Timestamps两个时间戳之间的 Firebase Firestore 查询
【发布时间】:2020-04-17 08:49:38
【问题描述】:

我想查找现在和即将到来(未来 30 天)但也不是过去的事件。

当我将它作为云函数运行时,我得到“不能在多个属性上使用不等式过滤器”。我是如何获得这种类型的数据的。

(忽略日期的东西有点乱,我还在玩)。

// Create date 30 days in future
const searchData: Date = new Date();
searchData.setDate(searchData.getDate() + 30);

// Load data and handle empty respoonse
const response: admin.firestore.QuerySnapshot = await admin
    .firestore()
    .collection(Collections.EVENTS)
    .where("startDate", "<=", admin.firestore.Timestamp.fromMillis(searchData.valueOf()))
    .where("endDate", ">=", admin.firestore.Timestamp.fromMillis(new Date().valueOf()))
    .where("public", "==", true)
    .limit(NUMBER_OF_EVENTS)
    .get();

编辑: 我想知道数据结构/查询方法,它将允许我返回事件集合中现在正在进行或将在下个月开始的所有事件。此外,我希望查询排除已经完成的事件。每个文档(事件)上都有一个 startDate 和 endDate 时间戳。

【问题讨论】:

  • 您不能在单个查询中对多个字段使用范围比较,但如果您编辑问题以说明您的查询应该做什么(英文),可能会有一种解决方法我们可以提供帮助。它可能涉及执行两个查询并合并结果。
  • 感谢您的回复,我已经更新了底部的问题,并描述了我正在寻找的行为。
  • 谢谢。您的问题对我帮助很大(确实是这个问题。我什至不滚动答案哈哈)。谢谢。

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


【解决方案1】:

由于您有两个字段要检查范围,因此我不确定这对于单个查询是否可行。相反,您可以执行两个查询,在客户端合并结果,然后执行最终过滤以获得完全匹配。

  1. 假设事件的最长持续时间。将这段时间称为“X”。
  2. 查询 startDate 大于 now - X 且小于 now + 30 天的所有文档。将此结果集称为“A”。
  3. 查询 endDate 大于 now 且小于 now + 30 天的所有文档。将此结果集称为“B”。
  4. 在客户端上,迭代 A 和 B 的所有结果,检查开始日期和结束日期是否符合您想要的条件。

我想不出一种方法来构建您的数据,只需一个查询即可。

【讨论】:

  • 这对于大型数据集来说是一个糟糕的解决方案。
  • @OliverDixon 如果您有更好的选择,我很乐意看到您的解决方案。鉴于 Firestore 的查询约束(每个查询只有一个范围过滤器)与此文档架构(开始和结束日期分开)相结合,似乎没有很多其他选项。要么更改架构以支持所需的查询,要么接受这需要一些额外的开销。
  • 这是 Firestore 的真正问题!我们有一个可以返回 10,000 个结果的数据库。我们的解决方案是使用“选择”,否则服务器崩溃!
【解决方案2】:

我知道这是一个老话题,但答案可能对其他人有好处。

你可以像我最后做的那样做,就是你有一个 $start_date 和一个 $target_date。

然后你这样做:

<?php
$start = strtotime('2021-11-22');
$target = strtotime('2022-01-01 0:00:00');

$limit = (($target - $start) / 86400);

$query = $col_data->where('date.day_start', '>=', $start);
$query = $query->limit($limit);

?>

还不错吧?欢迎您!

【讨论】:

  • 您介意解释一下这里的限制吗?它只会从 day_start 获取 start + limit 的文档?
【解决方案3】:

来自文档:

您只能对单个字段执行范围比较(、>=),并且在复合查询中最多可以包含一个 array-contains 或 array-contains-any 子句:

citiesRef.where("state", ">=", "CA").where("state", "<=", "IN");
citiesRef.where("state", "==", "CA").where("population", ">", 1000000);

https://firebase.google.com/docs/firestore/query-data/queries

【讨论】:

  • 这并没有为问题提供任何解决方案,而是重新迭代了 OP 已经知道的内容。
  • @SizzlingSquiggle 它确实在 OP 进行编辑之前回答了这个问题。 OP收到错误,这个答案向他们解释了他们收到错误的原因。还考虑到 Firestore 中查询的限制,这是最好的解决方案。
猜你喜欢
  • 2014-01-28
  • 2020-10-22
  • 1970-01-01
  • 2023-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多