Restrizioni per le query

Questa pagina illustra le limitazioni relative alle query su Datastore da Google App Engine. Di seguito sono riportate le limitazioni comuni che riscontrerai durante lo sviluppo per 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 avere un valore (eventualmente nullo) per ogni proprietà denominata nei filtri e negli ordini di ordinamento della query. In caso contrario, l'entità viene omessa dagli indici utilizzati per eseguire la query e di conseguenza non verrà inclusa nei risultati della query.

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

Una query non può trovare i valori delle proprietà non indicizzati né ordinare in base a queste proprietà.

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

Per evitare di dover eseguire la scansione dell'intero indice, il meccanismo di query si basa sul fatto che tutti i potenziali risultati di una query siano adiacenti nell'indice. Per soddisfare questo vincolo, una singola query non può utilizzare confronti di diseguaglianza (<, <=, >, >=) su più di una proprietà in tutti i relativi filtri. Ad esempio, la seguente query è valida perché entrambi i filtri di disuguaglianza si applicano alla stessa proprietà:

q := datastore.NewQuery("Person").
	Filter("BirthYear >=", minBirthYear).
	Filter("BirthYear <=", maxBirthYear)

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

q := datastore.NewQuery("Person").
	Filter("BirthYear >=", minBirthYear).
	Filter("Height <=", maxHeight) // ERROR

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

q := datastore.NewQuery("Person").
	Filter("LastName =", targetLastName).
	Filter("City =", targetCity).
	Filter("BirthYear >=", minBirthYear).
	Filter("BirthYear <=", maxBirthYear)

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

Quando una query non specifica un criterio di ordinamento, i risultati vengono restituiti nell'ordine in cui vengono recuperati. Con l'evoluzione dell'implementazione di Datastore (o se gli indici di un'applicazione cambiano), questo ordine può variare. Pertanto, se la tua applicazione richiede che i risultati della query vengano visualizzati in un determinato ordine, assicurati di specificare questo ordinamento esplicitamente 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 l'ordine di ordinamento specificato per quella proprietà. Si tratta di una semplice ottimizzazione per risparmiare sull'elaborazione non necessaria per le proprietà con un solo valore, poiché tutti i risultati hanno lo stesso valore per la proprietà e quindi non è necessaria un'ulteriore ordinamento. Tuttavia, le proprietà con più valori possono avere valori aggiuntivi oltre a quello corrispondente al filtro di uguaglianza. Poiché questo caso d'uso è raro e l'applicazione dell'ordinamento sarebbe costosa e richiederebbe indici aggiuntivi, il pianificatore delle query di Datastore ignora semplicemente l'ordinamento anche nel caso di valori multipli. Ciò potrebbe causare la restituzione dei risultati della query in un ordine diverso da quello che sembra suggerire l'ordinamento.

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

Per recuperare tutti i risultati corrispondenti a un filtro di disuguaglianza, una query esegue la scansione dell'indice per trovare la prima riga corrispondente al filtro, quindi esegue la scansione in avanti fino a quando non trova una riga non corrispondente. Affinché le righe consecutive includano l'intero insieme di risultati, 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ù ordini di ordinamento, il primo ordine di ordinamento deve fare riferimento alla stessa proprietà denominata nei filtri di disuguaglianza. La seguente è una query valida:

q := datastore.NewQuery("Person").
	Filter("BirthYear >=", minBirthYear).
	Order("BirthYear").
	Order("LastName")

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

q := datastore.NewQuery("Person").
	Filter("BirthYear >=", minBirthYear).
	Order("LastName") // ERROR

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

q := datastore.NewQuery("Person").
	Filter("BirthYear >=", minBirthYear).
	Order("LastName").
	Order("BirthYear") // ERROR

Le proprietà con più valori possono comportarsi in modi inaspettati

A causa del modo in cui vengono indicizzate, le entità con più valori per la stessa proprietà a volte possono interagire con i filtri delle query e gli ordini di ordinamento in modi inaspettati e sorprendenti.

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

q := datastore.NewQuery("Widget").
	Filter("x >", 1).
	Filter("x <", 2)

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

q := datastore.NewQuery("Widget").
	Filter("x =", 1).
	Filter("x =", 2)

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

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

  • Se i risultati della query sono ordinati 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.
  • Gli altri valori non influiscono sull'ordine di ordinamento né sul numero di valori.

Ciò ha la conseguenza insolita che un'entità con valori di proprietà 1 e 9 precede un'altra con valori 4, 5, 6 e 7 sia in ordine crescente che decrescente.

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

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