【问题标题】:How to query among two fields in firestore?如何在firestore中的两个字段之间进行查询?
【发布时间】:2019-10-17 15:40:12
【问题描述】:

假设我有一个 Events 集合,其中包含 startTimestamp 和 endTimestamp 分别指示事件的开始时间和结束时间。

如何在 firestore 中查询事件是否正在直播/已完成/即将举行?

【问题讨论】:

  • 您一次只能查询其中一种状态 - 您无法从一次查询中获得全部三种状态。您要求的不是很复杂,我建议您尝试一下,然后将无法按您期望的方式工作的代码发回此处。
  • 我正在寻找一种状态。我尝试了不同的组合,主要是我受到不同领域的不等式运算符的限制。如果我需要实时状态,我需要查询 >startTimestamp 和
  • 有一个很好的答案,但问题需要澄清。当您定义“即将到来的”活动时,这是什么意思?你想知道从现在到时间结束的每一个事件吗?或者只是下周的事件?下个月?只是下一个事件?另外,当您询问生活时-根据什么生活?那么用户按下一个按钮并显示当前时间在开始时间之后和结束时间之前的所有事件?除了他们按下按钮,您还想要其他机制吗?
  • 即将到来的状态意味着活动即将开始。 Live 表示事件当前正在发生。已完成意味着活动日期已完成。这里假设 Event 是在某个地方举行的开发会议。
  • 我想通过 Firestore 查询了解哪些活动正在直播(当前正在发生)或即将发生哪些活动。

标签: firebase google-cloud-firestore


【解决方案1】:

如果startTimestampendTimestamp 属性都存在于数据库中并且是Date 类型并且不是 字符串或数字,那么您可以简单地使用查询来检查特定日期是否在范围内。

例如在 Android 中,如果您想检查特定日期是否在界限内,您可能会认为像下面这样的查询会起作用:

eventsRef.whereGreaterThanOrEqualTo("startTimestamp", yourDate)
    .whereLessThanOrEqualTo("endTimestamp", yourDate);

但它不会。您将收到带有以下消息的异常:

除 whereEqualTo() 之外的所有 where 过滤器都必须位于同一字段上。但是您在“startTimestamp”和“endTimestamp”上有过滤器

您唯一的解决方案是创建三个单独的查询。

编辑:

根据您的评论,一个查询应该检查您的yourDate 是否在startTimestamp 之前

eventsRef.whereLessThanOrEqualTo("startTimestamp", yourDate);

如果是,则表示这是即将发生的事件。

第二个是看它是否比startTimestamp更重要:

eventsRef.whereGreaterThanOrEqualTo("startTimestamp", yourDate);

我们有两个案例。一种情况,你执行一个新的(第三个)查询来检查数据是否小于endTimestamp

eventsRef.whereLessThanOrEqualTo("endTimestamp", yourDate);

如果是,则表示该事件在范围内,因此是现场事件,否则表示该事件已结束。

要实时获取该数据,您应该为每个查询使用快照侦听器。

【讨论】:

  • 您能否解释一下您所说的三个单独的查询是什么意思?例如:请考虑获取 Live 状态。
  • 感谢您的回答。一旦我们对 Live 案例执行了 2 次查询,我该如何对其应用限制过滤器,因为 api 是这样的 - getSubscribedEvents(limit:10, offset:0, Status.Live);
  • 要限制结果,只需使用limit() 调用并传递您想要的确切限制,例如limit(10)
  • 但是一旦我们对这两个查询进行交集,这可能不会给出预期的最大结果计数。
  • 它没有回答限制部分,但我需要接受所述解决方案是唯一可行的方法。但是,我有另一个有效的解决方案,它通过对 subscribedEvents 集合的微小结构更改来解决限制问题。稍后会尝试并发布。
【解决方案2】:

以下是处理这种情况的案例。我很确定这是一个非常常见的问题,但在任何地方都没有找到有效的解决方案。

解决方案 1:将所有文档放在一个名为 subscribedEvents 的集合中 正如 Alex 所建议的那样,我们需要为以下状态做一些事情。

即将推出:currentTimestamp

完成:currentTimestamp > endTimestamp

Live:第一个查询中的 currentTimestamp > startTimestamp 和第二个查询中的 currentTimestamp

问题:我可以在 subscribedTimestamp 中有很多文档(近 10,000 个),并且 Live 条件不可扩展,因为我在查询时无法限制结果。由于它需要与两个查询相交,所以我需要在没有过滤器的情况下进行查询。

解决方案 2:这有点小技巧,但可扩展。不要将所有文档都放在一个子集合中。分离 Upcoming 事件并将这些文档放在 subscribedEvents/others/Upcoming 集合中。

用户订阅时,如果是即将发生的事件,可以直接存储在subscribedEvents/others/Upcoming集合中。

其余文档可以直接进入 subscribedEvents 集合。

即将到来的:从 subscribedEvents/others/Upcoming 集合中查询所有带有限制过滤器的文档。

完成:currentTimestamp > endTimestamp

直播 : currentTimestamp

这种结构的好处是我们可以应用限制过滤器,并且不需要为您的查询读取大量文档,并且每个状态只需要一个查询。

现在这一步还需要一个 cron 作业,以确保即将到来的子集合中的即将到来的事件被移回 subscribedEvents。

但是,如果您的文档较少,则可以使用解决方案 1。但对我来说不是。

希望它能帮助那些必须有效扩展的人。

【讨论】:

    猜你喜欢
    • 2023-01-22
    • 2011-02-07
    • 2018-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-11
    • 2020-04-17
    • 2023-03-07
    相关资源
    最近更新 更多