【问题标题】:How to compare multiple dates on an NDB query?如何比较 NDB 查询中的多个日期?
【发布时间】:2017-04-06 11:11:01
【问题描述】:

我需要在NDB queries 上获取与给定开始和结束日期匹配的对象,但我无法执行这个传统上简单的查询,因为 NDB 抱怨:

from google.appengine.ext import ndb
from datetime import datetime
from server.page.models import Post

now = datetime.now()
query = Post.query(
    Post.status == Post.STATUS_ACTIVE,
    Post.date_published_start <= now,
    Post.date_published_end >= now,
)
count = query.count()

错误:

BadRequestError: Only one inequality filter per query is supported.
Encountered both date_published_start and date_published_end

有解决办法吗?

【问题讨论】:

  • 您始终可以获取满足其中一个不等式查询的实体,并在 Python 中过滤另一个不等式。
  • @JeffO'Neill 我需要查询,因为我想对这些进行分页,而不仅仅是获取单个对象,而且迭代数千个对象效率极低。

标签: python google-app-engine google-cloud-datastore app-engine-ndb webapp2


【解决方案1】:

由于每个查询限制单个不等式过滤器的限制,无法动态获取可直接用于分页而无需任何进一步处理的单个结果列表。相关GAE 4301 issue

正如 Jeff 所提到的,通过一个不等式(理想情况下是最严格的一个)进行过滤,然后对结果进行进一步的动态处理始终是一种选择,正如您所指出的那样效率低下,但如果您需要完全灵活的搜索,这是不可避免的。

您可以通过使用 projection query 来提高性能 - 减少从数据存储传输到相关属性的数据量。

您也可以尝试执行 2 keys-only queries,每个不等式一个,然后计算结果的交集 - 这可以更快地为您提供分页计数和实体列表(作为键)。最后,您将通过直接键查找页面列表中的键获得当前页面的实体,理想情况下是批处理(使用ndb.get_multi())。

根据预期用途,您可能在某些情况下还有其他选择(当然需要额外的工作)。

您可以限制查询的范围。与其从一开始就查询所有Post 实体,不如在某些情况下只得到某个年份或某个月份的结果就足够了。然后您可以添加 year 和/或 month Post 属性,您可以将它们作为相等过滤器包含在查询中,从而可能将动态处理的结果数量从数千减少到数百或更少。

对于典型的、经常使用的情况,您也可以完全避免查询。例如,如果预期用途是生成几种月度报告,您可以拥有一些 Report 实体,其中包含每个此类报告类型/月的 Post 键列表,您可以在 Post 实体的相关属性更改时更新这些键.而不是查询Posts 实体以获取报告,而只需使用来自相应Report 实体的现有列表。您还可以在生成时存储/缓存实际报告,以便直接重复使用(而不是在每次访问时重新生成)。

【讨论】:

    【解决方案2】:

    使用多个过滤器和不等式进行查询的另一种解决方法是使用搜索 API。 https://cloud.google.com/appengine/training/fts_adv/lesson1#query_options

    来自文档:

    例如查询job tag:"very important" sent &lt; 2011-02-28 查找在任何字段中具有术语作业的文档,并且还包含 在标签字段中非常重要的短语,以及之前的发送日期 2011 年 2 月 28 日。

    只需将数据存储区查询中的数据放入搜索文档,然后对这些文档运行查询即可。

    【讨论】:

      猜你喜欢
      • 2013-03-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-26
      • 1970-01-01
      • 2013-09-16
      • 2020-04-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多