不等式过滤日期和数字

时间:2011-02-01 12:27:45

标签: python google-app-engine date inventory

我正在尝试查询我的Google App Engine数据存储[Python],其中包含item_name,manufacturing_date和number_of_items_shipped。数据存储区中有大约100万条记录并且不断增加。

场景: 获取 x_items [用户输入]以及 some_date [用户输入]之后 基本上,是一种库存检查。

有效的2个属性不等式。 但是由于GAE中的restrictions on queries,我无法做到这一点。

搜索此问题的SO。但是,到现在为止没有运气。你有没遇到过这个问题?如果是这样,你能解决这个问题吗?请告诉我。

同样在Google I / O 2010中,Next Gen Queries,Alfred Fuller提到他们很快就会删除此限制。已经超过8个月了,但这种限制现在已经存在。不幸的是

如果有人能够绕过这种限制,那么任何人都可以发表答案。

非常感谢。

2 个答案:

答案 0 :(得分:1)

基于Sudhir的回答,我可能会根据您关注的粒度将每条记录分配到生产日期“桶”。如果您的制造日期范围超过几年,请使用月度桶。如果您的范围是去年,那么每周一次。

现在,当您想要使用>查找记录时n在给定范围内的销售和制造日期,在该范围内每个桶执行一次查询,并过滤掉您不感兴趣的项目。

例如(完全未经测试):

BUCKET_SIZE_DAYS = 10

def put(self):
    self.manufacture_bucket = int(self.manufacture_date.toordinal() / BUCKET_SIZE_DAYS)
    super(self.__class__, self).put()

def filter_date_after(self, date_start):
    first_bucket = int(date_start.toordinal() / BUCKET_SIZE_DAYS)
    last_bucket = int(datetime.datetime.today().toordinal() / BUCKET_SIZE_DAYS)

    for this_bucket in range(first_bucket, last_bucket+1):
        for found in self.filter("manufacture_bucket =", this_bucket):
            if found.manufacture_date >= date_start:
                yield found

然后您应该可以使用它:

widgets.filter("sold >", 7).filter_date_after(datetime.datetime(2010,11,21))

留给读者练习:

  • 使其与添加到最后的其他过滤器完美搭配
  • 多个存储桶大小允许您始终查询ln(日期范围内的日期)存储桶。

答案 1 :(得分:0)

不幸的是,您无法绕过此限制,但我可以帮助您以稍微不同的方式对数据建模。

首先,Bigtable非常适合快速读取大型数据库 - 当有一百万人同时点击您的应用时,您会这样做。你在这里要做的是关于历史数据的报告。虽然我建议将报告移动到RDBMS,但有一种方法可以在Bigtable上完成。

首先,覆盖项目模型上的put()方法,以便在保存日期之前拆分日期。你会做什么就像

def put(self):
  self.manufacture_day = self.manufacture_date.day
  self.manufacture_month = self.manufacture_date.month
  self.manufacture_year = self.manufacture_date.year
  super(self.__class__, self).put()

您可以按照您想要的任何粒度级别执行此操作,即使是小时,分钟,秒等等。

只需加载并保存您的商品实体,即可将其追溯应用于您的数据库。 mapper非常方便。

然后更改您的查询以仅对项目计数使用不等式,并使用正常的等值选择您想要的天/月/年。您可以通过触发多个查询或使用IN子句来执行范围。 (无论如何,这也是一样的。)

这看起来似乎很难做,但请记住,如果你这样做,你的报告几乎会立即运行,即使有数百万人试图同时运行它们。你可能不需要这种规模,但是......这就是你得到的:D