2009-07-25 15 views
5

Ho un modello, di seguito, e vorrei ottenere tutti i distinti valori area. L'equivalente SQL è select distinct area from tutorialsCome ottenere il valore distinto di uno dei miei modelli in Google App Engine

class Tutorials(db.Model): 
    path = db.StringProperty() 
    area = db.StringProperty() 
    sub_area = db.StringProperty() 
    title = db.StringProperty() 
    content = db.BlobProperty() 
    rating = db.RatingProperty() 
    publishedDate = db.DateTimeProperty() 
    published = db.BooleanProperty() 

so che in Python posso fare

a = ['google.com', 'livejournal.com', 'livejournal.com', 'google.com', 'stackoverflow.com'] 
b = set(a) 
    b 
    >>> set(['livejournal.com', 'google.com', 'stackoverflow.com']) 

ma che mi richiederebbe spostare gli oggetti fuori della query zona in un'altra lista e poi eseguire set contro la lista (sembra molto inefficiente) e se ho un oggetto distinto che si trova nella posizione 1001 nell'archivio dati non lo visualizzerei a causa del limite di recupero di 1000.

Vorrei ottenere tutti i valori distinti dell'area nel mio archivio dati per scaricarlo sullo schermo come l inchiostri.

risposta

7

Datastore non può farlo per te in una singola query. Una richiesta di archivio dati restituisce sempre un blocco consecutivo di risultati da un indice e un indice consiste sempre di tutte le entità di un determinato tipo, ordinate in base a qualsiasi ordine specificato. Non c'è modo per la query di saltare gli elementi solo perché un campo ha valori duplicati.

Un'opzione è di ristrutturare i dati. Ad esempio, introdurre un nuovo tipo di entità che rappresenta una "area". Aggiungendo un Tutorial crei la corrispondente "area" se non esiste già, e cancellando un Tutoral elimina la corrispondente "area" se nessun Tutorial rimane con la stessa "area". Se ciascuna area memorizzava un conteggio di tutorial in quell'area, questo potrebbe non essere troppo oneroso (anche se mantenere le cose coerenti con le transazioni eccetera sarebbe in effetti piuttosto laborioso). Mi aspetto che la chiave dell'entità possa essere basata sulla stringa di area stessa, il che significa che puoi sempre fare ricerche chiave piuttosto che query per ottenere le entità dell'area.

Un'altra opzione è utilizzare un lavoro in coda o cron per creare periodicamente un elenco di tutte le aree, accumulandolo su più richieste se necessario, e inserire i risultati nel datastore o in memcache. Ciò significherebbe naturalmente che l'elenco delle aree potrebbe essere temporaneamente non aggiornato a volte (o se ci sono cambiamenti costanti, potrebbe non essere mai interamente aggiornato), che potrebbe essere o meno accettabile per te.

Infine, se è probabile che ci siano poche aree rispetto ai tutorial, è possibile farlo al volo richiedendo il primo Tutorial (ordinato per area), quindi richiedendo il primo Esercitazione la cui area è maggiore dell'area di il primo e così via. Ma questo richiede una richiesta per area distinta, quindi è improbabile che sia veloce.

+0

Va bene. Rimuoverei il "per quanto ne so", personalmente. :) –

+0

Grazie per la risposta. Penso di poter fare l'idea della ristrutturazione. Anch'io speravo che esistesse un modo oscuro per farlo – AutomatedTester

0

This has been asked before, e la conclusione è stata che l'utilizzo di set va bene.

+0

La domanda era come usare Python per filtrare il risultato. La domanda qui vuole spiegare il caso in cui ci sono 1001 o più tutorial, e quindi una singola query non può restituirli. –

1

La parola chiave DISTINCT è stata introdotta nella versione 1.7.4.

Problemi correlati