0

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

场景:获取所有发货超过x_items [用户输入] 并在 some_date [用户输入]之后制造的 item_name 。基本上,一种库存检查。

实际上有 2 个属性不等式。但由于GAE中的查询限制,我无法做到这一点。

搜索了这个问题。但是,到目前为止还没有运气。你遇到过这个问题吗?如果是这样,你能解决这个问题吗?请告诉我。

同样在 Google I/O 2010 的Next Gen Queries中,Alfred Fuller 提到他们将很快取消这个限制。已经8个多月了,但这个限制现在仍然存在。很遗憾。

如果有人能够规避此限制,请感谢是否有人可以发布答案。

非常感谢。

4

2 回答 2

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(日期范围内的天数)存储桶。
于 2011-02-28T08:54:49.037 回答
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()

您可以按所需的任何粒度级别执行此操作,甚至是小时、分钟、秒等。

您可以通过加载和保存您的项目实体将其追溯应用到您的数据库。映射器对此非常方便。

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

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

于 2011-02-01T13:10:41.737 回答