Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Appengine filter inequality and ordering fails

Tags:

I think I'm overlooking something simple here, I can't imagine this is impossible to do.

I want to filter by a datetime attribute and then order the result by a ranking integer attribute. When I try to do this:

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

I get the following:

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

Huh? What am I missing?

Thanks.

like image 568
dave paola Avatar asked Apr 19 '10 23:04

dave paola


2 Answers

The datastore isn't capable of ordering a query that contains an inequality by any property other than the one used in the inequality.

This can often be worked around by adding a property that can be filtered with an equality; in this case, it may be possible to have a BooleanProperty tracking whether an entity is from the current week, and update it for all entities at the end of each week.

like image 83
Wooble Avatar answered Oct 02 '22 21:10

Wooble


I used another trick, which worked out simply because of the format I needed my data in (a list of dicts). In this case I run the datetime-based query, create dicts from the returned ents, and then sort by the numeric 'counter' property. Reversing the sort gave me a descending order. Keep in mind I only requested 10 results, on a fairly small datastore.

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) 

Example result:

[{'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'}] 
like image 22
Kai Avatar answered Oct 02 '22 20:10

Kai