2010-04-19 12 views
23

Credo di essere qualcosa di semplice che si affaccia qui, non riesco a immaginare questo è impossibile da fare.AppEngine la disuguaglianza e l'ordinamento non riesce

voglio filtrare da un attributo datetime e poi ordinare il risultato da un attributo integer classifica. Quando provo a fare questo:

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

ottengo il seguente:

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

Eh? Cosa mi manca?

Grazie.

risposta

20

L'archivio dati non è in grado di ordinare una query che contiene una disuguaglianza da qualsiasi struttura diversa da quella utilizzata nella disuguaglianza.

Questo spesso può essere risolto con l'aggiunta di una proprietà che può essere filtrato con un'uguaglianza; in questo caso, può essere possibile avere una BooleanProperty monitoraggio se un'entità è dalla settimana corrente, e aggiornarlo per tutte le entità alla fine di ogni settimana.

+0

Grazie. Come posso scrivere qualcosa per aggiornare il mio intero datastore se tutte le mie richieste richiedono solo 10 secondi? –

+1

30 secondi, non 10, e puoi usare qualcosa come questo: http://blog.notdot.net/2010/03/Annuncio-a-robust-datastore-bulk-update-utility-for-App-Engine –

+0

Nick : Sembra davvero molto utile. Molte grazie. –

3

ho usato un altro trucco, che ha lavorato in modo semplice a causa del formato di cui avevo bisogno dei miei dati in (un elenco di dicts). In questo caso, eseguo la query basata su data/ora, creo i valori da ents restituiti e quindi eseguo l'ordinamento in base alla proprietà numerica 'counter'. L'inversione della specie mi ha dato un ordine decrescente. Tieni presente che ho richiesto solo 10 risultati, su un datastore piuttosto piccolo. risultato

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) 

Esempio:

[{'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

Il modo più semplice sarebbe quella di dividere la vostra richiesta:

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

questo probabilmente funzionerebbe solo con ndb anche se –

-1

non so da quando, ma SDK corrente può restituire l'errore sottile diverso :

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

Nel mio caso, Potrei risolvere l'errore con questo:

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

Redatta 2013/02/08: Come Horselover Fat menzionato in un commento, evita solo un errore.

+5

questo evita il errore di runtime, ma non fa quello che vuoi! (testato in 'db' comunque) - restituisce semplicemente la query ordinata per' submit'! – HorseloverFat

+0

Sì, hai ragione. Quando ho scritto la risposta, ho pensato che funzionasse comunque. – hiroshi

Problemi correlati