Неравенство Фильтры по дате и номеру - PullRequest
0 голосов
/ 01 февраля 2011

Я пытаюсь запросить мое хранилище данных Google App Engine [Python], которое имеет item_name, manufacturing_date и number_of_items_shipped.В хранилище данных ~ 1,0 млн. Записей, и их количество постоянно увеличивается.

Сценарий: получить все имена элементов, которые были отправлены более чем x_items [пользовательский ввод] и изготовлены после some_date [пользовательский ввод].В основном, вид инвентарной проверки.

Эффективно 2 неравенства по свойствам.Но из-за ограничений на запросы в GAE я не могу этого сделать.

Поиска SO для этой проблемы.Но не повезло до сих пор.Вы сталкивались с этой проблемой?Если да, то смогли ли вы решить эту проблему?Пожалуйста, дайте мне знать.

Также в Google I / O 2010, Next Gen Queries Альфред Фуллер упомянул, что они собираются снять это ограничение в ближайшее время.Прошло уже более 8 месяцев, но это ограничение действует даже сейчас.К сожалению.

Спасибо, если кто-то может опубликовать ответ, если они смогли обойти это ограничение.

Большое спасибо.

Ответы [ 2 ]

1 голос
/ 28 февраля 2011

Опираясь на ответ Судхира, я, вероятно, назначил бы каждую запись на «ведро» даты изготовления, исходя из степени детализации, которая вас интересует. Если ваш срок изготовления превышает пару лет, используйте, например, месячные ведра. Если ваш диапазон только в прошлом году, еженедельно.

Теперь, когда вы хотите найти записи с> 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 (дней в диапазоне дат).
0 голосов
/ 01 февраля 2011

К сожалению, вы не можете обойти это ограничение, но я могу помочь вам смоделировать данные немного по-другому.

Во-первых, 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...