Appengine фильтр неравенств и упорядочение не удается - PullRequest
23 голосов
/ 20 апреля 2010

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

Я хочу отфильтровать по атрибуту 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

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

Спасибо.

Ответы [ 5 ]

20 голосов
/ 20 апреля 2010

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

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

3 голосов
/ 08 апреля 2015

В хранилище данных есть некоторые ограничения на запросы. Нельзя объединять фильтр неравенства по одному свойству с порядком по другому свойству. Вы можете найти больше ограничений здесь:

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

3 голосов
/ 28 июля 2010

Я использовал другой прием, который сработал просто из-за формата, в котором мне нужны были мои данные (список диктовок). В этом случае я запускаю запрос на основе даты и времени, создаю 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'}]
0 голосов
/ 20 ноября 2012

С тех пор не знаю, но текущий 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, оно позволяет избежать только ошибки.

0 голосов
/ 10 августа 2012

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

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