Appengine过滤器不等式和排序失败

24 投票
5 回答
7071 浏览
提问于 2025-04-15 21:48

我觉得我可能忽略了一些简单的东西,我无法想象这件事是不可能做到的。

我想根据一个日期时间的属性进行筛选,然后再根据一个排名的整数属性来排序结果。当我尝试这样做的时候:

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 个回答

3

Datastore在查询方面有一些限制。其中一个限制是,不能在一个属性上使用不等式过滤器,同时在另一个属性上进行排序。你可以在这里找到更多的限制信息:

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

3

我用了另一个小技巧,这个技巧之所以有效,是因为我需要的数据格式是(字典的列表)。在这种情况下,我先运行基于日期时间的查询,然后从返回的结果中创建字典,接着根据数字类型的“计数器”属性进行排序。把排序结果反转一下,就得到了降序排列。需要注意的是,我只请求了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'}]
20

这个数据存储系统不能对包含不等式的查询进行排序,除了用在不等式中的那个属性以外。

不过,我们可以通过添加一个可以用等式过滤的属性来解决这个问题。比如,我们可以增加一个布尔属性,用来记录某个实体是否属于当前这一周,并在每周结束时更新所有实体的这个属性。

撰写回答