Подтвердить что ты не робот

Неверное неравенство и упорядочение фильтра приложений

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

Я хочу фильтровать атрибут datetime, а затем заказывать результат по атрибуту целочисленного значения. Когда я пытаюсь сделать это:

query.filter("submitted >=" thisweek).order("ranking")

Я получаю следующее:

BadArgumentError: First ordering property must be the same as inequality filter property, if specified for this query; received ranking, expected submitted

А? Что мне не хватает?

Спасибо.

4b9b3361

Ответ 1

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

Это часто можно обойти, добавив свойство, которое можно фильтровать с помощью равенства; в этом случае может быть возможно отслеживать BooleanProperty, является ли объект с текущей недели, и обновлять его для всех объектов в конце каждой недели.

Ответ 2

Я использовал еще один трюк, который работал просто из-за формата, в котором мне нужны мои данные (список dicts). В этом случае я запускаю запрос на основе даты и времени, создаю dicts из возвращаемых значений, а затем сортирую по числовому свойству "counter". Реверсирование сортировки дало мне убывающий порядок. Имейте в виду, что я попросил только 10 результатов на довольно небольшом хранилище данных.

q = food.Food.all()
q.filter("last_modified <=", now)
q.filter("last_modified >=", hour_ago)

ents = q.fetch(10)

if ents:
  results = [{
    "name": ent.name,
    "counter": ent.counter
    } for ent in ents]

  # reverse list for 'descending' order
  results.sort(reverse=True)

Результат:

[{'counter': 111L, 'name': u'wasabi'}, {'counter': 51L, 'name': u'honeydew'}, {'counter': 43L, 'name': u'mars bar'}, {'counter': 37L, 'name': u'scallop'}, {'counter': 33L, 'name': u'turnip'}, {'counter': 29L, 'name': u'cornbread'}, {'counter': 16L, 'name': u'mackerel'}, {'counter': 10L, 'name': u'instant coffee'}, {'counter': 3L, 'name': u'brussel sprouts'}, {'counter': 2L, 'name': u'anchovies'}]

Ответ 3

У Datastore есть некоторые ограничения на запросы. Один из них не позволяет комбинировать фильтр неравенства по одному свойству с порядком по свойству пыльника. Здесь вы можете найти дополнительные ограничения:

https://cloud.google.com/appengine/docs/python/ndb/queries

Ответ 4

Самый простой способ - разделить запрос:

q1 = query.filter("submitted >=" thisweek)
q2 = q1.order("ranking")

Ответ 5

С тех пор я не знаю, но текущий SDK может возвращать незначительную ошибку:

BadArgumentError: First ordering property must be the same as inequality filter property, if specified for this query; received ranking, expected submitted

В моем случае я мог бы обойти ошибку с этим:

query.filter("submitted >=" thisweek).order("submitted").order("ranking")

Отредактировано 2013-02-08: Как упоминалось в комментарии Horselover Fat, он избегает ошибки.