Restrizioni relative alle query

Questa pagina illustra le limitazioni relative all'esecuzione di query su Datastore da Google App Engine. Di seguito sono elencate le limitazioni comuni che incontrerai durante lo sviluppo di Datastore.

Le entità prive di una proprietà denominata nella query vengono ignorate

Le entità dello stesso tipo non devono avere le stesse proprietà. Per essere idonea come risultato di una query, un'entità deve possedere un valore (possibilmente nullo) per ogni proprietà denominata nei filtri e nell'ordinamento della query. In caso contrario, l'entità viene omessa dagli indici utilizzati per eseguire la query e, di conseguenza, non sarà inclusa nei risultati della query.

Il filtro in base alle proprietà non indicizzate non restituisce risultati

Una query non può trovare i valori delle proprietà che non sono indicizzati né può ordinare su tali proprietà. Consulta la pagina Indici di Datastore per una discussione dettagliata sulle proprietà non indicizzate.

I filtri di disuguaglianza sono limitati a al massimo una proprietà

Per evitare di dover analizzare l'intero indice, il meccanismo di query si basa sul fatto che tutti i potenziali risultati di una query sono adiacenti l'uno all'altro nell'indice. Per soddisfare questo vincolo, una singola query non può utilizzare confronti di disuguaglianze (<, <=, >, >=, !=) in più di una proprietà in tutti i suoi filtri. Ad esempio, la seguente query è valida, perché entrambi i filtri di disuguaglianza si applicano alla stessa proprietà:

SELECT * FROM Person WHERE birth_year >= :min_birth_year
                       AND birth_year <= :max_birth_year

Tuttavia, questa query non è valida, perché utilizza filtri di disuguaglianza su due proprietà diverse:

SELECT * FROM Person WHERE birth_year >= :max_birth_year
                       AND height <= :max_height          # ERROR

Tieni presente che una query può combinare filtri di uguaglianza (=) per proprietà diverse, insieme a uno o più filtri di disuguaglianza su una singola proprietà. Pertanto, la seguente è una query valida:

SELECT * FROM Persona WHERE last_name = :target_last_name AND città = :target_city AND anno_nascita >= :anno_nascita_min AND anno_nascita <= :max_birth_year

L'ordinamento dei risultati della query non è definito se non è specificato alcun ordinamento

Quando per una query non è specificato un ordinamento, i risultati vengono restituiti nell'ordine in cui sono stati recuperati. Man mano che l'implementazione di Datastore si evolve (o se gli indici di un'applicazione cambiano), questo ordine potrebbe cambiare. Pertanto, se la tua applicazione richiede i risultati della query in un determinato ordine, assicurati di specificare tale ordinamento in modo esplicito nella query.

Gli ordini di ordinamento vengono ignorati nelle proprietà con filtri di uguaglianza

Le query che includono un filtro di uguaglianza per una determinata proprietà ignorano qualsiasi ordinamento specificato per quella proprietà. Si tratta di una semplice ottimizzazione per evitare un'elaborazione inutile per le proprietà a un singolo valore, poiché tutti i risultati hanno lo stesso valore per la proprietà e quindi non è necessario un ulteriore ordinamento. Le proprietà a più valori, tuttavia, possono avere valori aggiuntivi oltre a quello corrispondente al filtro di uguaglianza. Poiché questo caso d'uso è raro e l'applicazione dell'ordinamento sarebbe costoso e richiedere indici aggiuntivi, lo strumento di pianificazione delle query di Datastore ignora semplicemente l'ordinamento anche nel caso a più valori. Di conseguenza, i risultati della query potrebbero essere restituiti in un ordine diverso da quello previsto.

Le proprietà utilizzate nei filtri di disuguaglianza devono essere ordinate per prime

Per recuperare tutti i risultati che corrispondono a un filtro di disuguaglianza, una query analizza l'indice per trovare la prima riga corrispondente al filtro, quindi esegue la scansione in avanti finché non trova una riga non corrispondente. Affinché le righe consecutive includano l'insieme di risultati completo, devono essere ordinate in base alla proprietà utilizzata nel filtro di disuguaglianza prima di qualsiasi altra proprietà. Pertanto, se una query specifica uno o più filtri di disuguaglianza insieme a uno o più ordinamenti, il primo deve fare riferimento alla stessa proprietà denominata nei filtri di disuguaglianza. Di seguito è una query valida:

SELECT * FROM Persona WHERE anno_nascita >= :min_nascita_anno ORDINE PER anno di nascita, cognome

Questa query non è valida perché non ordina in base alla proprietà utilizzata nel filtro di disuguaglianza:

SELECT * FROM Persona WHERE anno_nascita >= :min_nascita_anno ORDER BY last_name # ERRORE

Analogamente, questa query non è valida perché la proprietà utilizzata nel filtro di disuguaglianza non è la prima ordinata:

SELECT * FROM Person WHERE birth_year >= :min_birth_year
                     ORDER BY last_name, birth_year       # ERROR

Le proprietà con più valori possono comportarsi in modo sorprendente

A causa della modalità di indicizzazione, le entità con più valori per la stessa proprietà a volte possono interagire con i filtri di query e ordinare gli ordini in modi inaspettati e sorprendenti.

Se una query ha più filtri di disuguaglianza su una determinata proprietà, un'entità corrisponderà alla query solo se almeno uno dei suoi singoli valori per la proprietà soddisfa tutti i filtri. Ad esempio, se un'entità di tipo Widget ha valori 1 e 2 per la proprietà x, non corrisponderà alla query:

SELECT * FROM Widget WHERE x > 1
                       AND x < 2

Ciascuno dei valori x dell'entità soddisfa uno dei filtri, ma nessuno dei due valori li soddisfa entrambi. Tieni presente che ciò non vale per i filtri di uguaglianza. Ad esempio, la stessa entità soddisferà la query

SELECT * FROM Widget WHERE x = 1
                       AND x = 2

anche se nessuno dei singoli valori x dell'entità soddisfa entrambe le condizioni di filtro.

L'operatore non uguale (!=) funziona come "il valore è diverso da" test. Quindi, ad esempio, la query

SELECT * FROM Widget WHERE x != 1

corrisponde a qualsiasi entità Widget con un valore x diverso da 1.

Analogamente, l'ordinamento delle proprietà a più valori è insolito. Poiché queste proprietà vengono visualizzate una sola volta nell'indice per ogni valore univoco, il primo valore visualizzato nell'indice determina l'ordinamento di un'entità:

  • Se i risultati della query sono in ordine crescente, per l'ordinamento viene utilizzato il valore più piccolo della proprietà.
  • Se i risultati sono ordinati in ordine decrescente, viene utilizzato il valore più alto per l'ordinamento.
  • Altri valori, così come il numero di valori, non influiscono sull'ordinamento.

Si tratta della conseguenza insolita che un'entità con i valori delle proprietà 1 e 9 precede un'entità con i valori 4, 5, 6 e 7 sia in ordine crescente che in ordine decrescente.

Le query all'interno delle transazioni devono includere i filtri dei predecessori

Le transazioni Datastore operano solo su entità che appartengono allo stesso gruppo di entità (derivanti da un predecessore comune). Per mantenere questa limitazione, tutte le query eseguite all'interno di una transazione devono includere un filtro predecessore che specifichi un predecessore nello stesso gruppo di entità delle altre operazioni nella transazione.