как сделать запрос по сумме в ndb

Я пытаюсь создать какой-то KPI на своем сайте и изо всех сил пытаюсь получить данные. например, допустим, я создаю блог с моделью:

class MyPost(ndb.Model):
    Author = ndb.KeyProperty(MyUser, required = True)
    when = TZDateTimeProperty(required = True)
    status = ndb.IntegerProperty(default = 1) # 1=draft, 2=published
    text = ndb.TextProperty()   

и я хочу создать запрос, в котором будут перечислены мои лучшие авторы, которые дадут мне результат (желательно отсортированный)

['Jack':10, 'Jane':8, 'Joe',0]

Я могу думать о 2 способах:

  • query().fetch() все элементы и подсчет вручную, тогда это очень неэффективно, но наиболее гибко
  • для автора в Users: result[author]=query(...).fetch().count() так себе эффективность и требует заранее знать мои индексы (не будет работать, если я хочу запросить "фаворит автора" домашний питомец"

какой из них предпочтительнее?

какие еще способы посоветуете?


person ido roseman    schedule 19.03.2015    source источник
comment
Сохраняйте промежуточный итог в сущности MyUser для каждого созданного сообщения. Тогда не надо ничего считать.   -  person Tim Hoffman    schedule 19.03.2015


Ответы (1)


Я бы рекомендовал денормализовать модель MyUser, то есть ввести избыточность, задав MyUser IntegerProperty, скажем, numposts, которые избыточно отслеживают, сколько MyPost объектов создал пользователь. Необходимость денормализации часто возникает в хранилищах данных NoSQL.

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

person Alex Martelli    schedule 19.03.2015
comment
Конечно, вы правы в этом. Но как я могу сделать его чувствительным ко времени? Поскольку это используется для KPI, мне нужны только недавние действия. Например: сообщения, написанные за последние 30 дней (или будущие действия, например, встречи, назначенные на предстоящую неделю в приложении календаря). - person ido roseman; 20.03.2015
comment
@idoroseman, вы можете сделать это, обновляя такие чувствительные ко времени денормализованные атрибуты в пакетном режиме в периодически выполняемом задании cron. - person Alex Martelli; 20.03.2015
comment
Это то, чего я боялся. Поскольку в этом задании cron я возвращаюсь к своим первоначальным запросам (хотя и в меньшем наборе данных) - person ido roseman; 20.03.2015