如何比较NDB查询上的多个日期



我需要在与给定的开始日期和结束日期匹配的NDB查询上获取对象,但是我无法进行传统上简单的查询,因为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

是否有任何解决方法?

动态获取单个结果列表,该列表可以直接用于分页而无需进行任何其他处理,这是由于每个查询限制的单个不等式过滤器的限制。相关GAE 4301发行。

正如杰夫(Jeff)提到的那样,通过一种不平等(理想情况下是最有限的)过滤,然后是对结果的进一步动态处理,始终是一种选择,如您所指出的那样效率低下,但是如果您需要搜索的总灵活性,则不可避免地是不可避免的。

您可以使用投影查询来提高性能 - 将从数据存储传输的数据量减少到相关属性。

您也可以尝试执行2个仅密钥查询,每个不平等问题一个,然后计算结果的相交 - 这可以使您更快地提供分页计数和实体列表(作为键)。最后,您将通过页面列表中的键的直接键查找来获取当前页面的实体,理想情况下(使用ndb.get_multi())。

根据预期的用法,您可能在某些情况下(当然需要其他工作)。

您可以限制查询的范围。与其查询所有Post实体,因为时间的开始,在某些情况下可能只是在特定年份或一个月中导致足够的时间。然后,您可以添加year和/或month Post属性,您可以在查询中作为平等过滤器包含该属性,从而有可能减少成千上万的结果的结果数量。

您还可以完全避免查询典型的,常用的情况。例如,如果预期的用途是生成几种每月报告,则可以使用一些Report实体,其中包含每个此类报告类别/月份的Post键列表,您可以在Post实体的相关属性更改时可以进行更新。而不是向报告查询Posts实体,而是只使用来自相应的Report实体的已经可用的列表。您也可以在生成时存储/缓存实际报告,以直接重复使用(而不是在每个访问中重新生成)。

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

来自文档:

例如,查询job tag:"very important" sent < 2011-02-28 在任何字段中查找具有作业一词的文档,还包含 短语在标签字段中非常重要,并且在 2011年2月28日。

只需将数据从数据存储查询放入搜索文档中并在这些文档上运行查询即可。

最新更新