2010-04-19 10 views
23

Ich denke, ich übersehen etwas Einfaches hier, ich kann mir nicht vorstellen, dass dies unmöglich ist zu tun.Appengine Filter Ungleichheit und Bestellung schlägt fehl

Ich möchte nach einem Datetime-Attribut filtern und dann das Ergebnis nach einem Ranking Integer-Attribut ordnen. Wenn ich versuche, dies zu tun:

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

ich folgendes:

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

Huh? Was vermisse ich?

Danke.

Antwort

20

Der Datenspeicher ist nicht in der Lage, eine Abfrage anzuordnen, die eine Ungleichung durch eine andere als die in der Ungleichung verwendete Eigenschaft enthält.

Dies kann oft umgangen werden, indem eine Eigenschaft hinzugefügt wird, die mit einer Gleichheit gefiltert werden kann; In diesem Fall kann es möglich sein, dass eine Boolesche Eigenschaft verfolgt, ob eine Entität aus der aktuellen Woche stammt, und sie für alle Entitäten am Ende jeder Woche aktualisieren.

+0

Danke. Wie kann ich etwas schreiben, um meinen gesamten Datenspeicher zu aktualisieren, wenn alle meine Anfragen nur 10 Sekunden dauern sollen? –

+1

30 Sekunden, nicht 10, und Sie können etwas wie folgt verwenden: http://blog.notdot.net/2010/03/Announcing-a-robust-datastore-bulk-update-utility-for-App-Engine –

+0

Nick : Das sieht wirklich sehr, sehr nützlich aus. Danke vielmals. –

3

Ich benutzte einen anderen Trick, der einfach wegen des Formats funktionierte, in dem ich meine Daten brauchte (eine Liste von Diktaten). In diesem Fall führe ich die Datetime-basierte Abfrage aus, erstelle Dicts aus den zurückgegebenen ents und sortiere dann nach der numerischen Eigenschaft 'counter'. Das Umkehren der Sortierung gab mir eine absteigende Reihenfolge. Bedenken Sie, dass ich nur 10 Ergebnisse in einem relativ kleinen Datenspeicher angefordert habe.

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) 

Beispiel Ergebnis:

[{'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'}] 
-1

Der einfachste Weg, um Ihre Abfrage zu spalten würde:

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

das würde wahrscheinlich nur mit ndb funktionieren, obwohl –

-1

Ich weiß nicht, seit wann, aber die aktuellen SDK zurückkehren kann subtil unterschiedliche Fehler :

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

In meinem Fall, Ich konnte mit dieser den Fehler umgehen:

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

Herausgegeben 2013.02.08: Wie Horselover Fat in einem Kommentar erwähnt, vermeidet nur einen Fehler.

+5

dies vermeidet Laufzeitfehler, aber es tut nicht, was Sie wollen! (sowieso in 'db' getestet) - es gibt einfach die Abfrage sortiert nach' submitted' zurück! – HorseloverFat

+0

Ja, du hast Recht. Als ich die Antwort schrieb, dachte ich, dass es funktioniert. – hiroshi