Cursori di query

I cursori di query consentono a un'applicazione di recuperare i risultati di una query batch e sono consigliati rispetto all'uso di offset interi per l'impaginazione. Per ulteriori informazioni sulla strutturazione delle query per la tua app, consulta Query.

Cursori di query

I cursori di query consentono a un'applicazione di recuperare i risultati di una query senza dover sostenere l'overhead di un offset di query. Dopo aver eseguito un'operazione di recupero, l'applicazione può ottenere un cursore, ovvero una stringa opaca codificata in base64 che indica la posizione dell'indice dell'ultimo risultato recuperato. L'applicazione può salvare questa stringa, ad esempio Datastore, in Memcache, in un payload di attività della coda di attività o incorporato in una pagina web come parametro HTTP GET o POST e può quindi utilizzare il cursore il punto di partenza per una successiva operazione di recupero allo scopo di ottenere il batch di risultati dal punto in cui è terminato il recupero precedente. Un recupero può anche specificare un cursore di fine per limitare l'ambito del set di risultati restituito.

Differenza tra offset e cursori

Anche se Datastore supporta gli offset interi, dovresti evitare di utilizzarli. Utilizza invece i cursori. L'utilizzo di un offset evita solo di restituire il valore ha saltato entità alla tua applicazione, ma queste entità vengono comunque recuperate internamente. Le entità ignorate in effetti influiscono sulla latenza della query e all'applicazione vengono addebitate le operazioni di lettura necessarie per recuperarle. Utilizzo i cursori al posto degli offset consente di evitare tutti questi costi.

Esempio di cursore di query

In Go, un'applicazione ottiene un cursore dopo aver recuperato i risultati della query chiamando il metodo Cursor del valore Iterator. Per recuperare risultati aggiuntivi dal punto del cursore, l'applicazione prepara una query simile con lo stesso tipo di entità, filtri e ordini di ordinamento e passa il cursore al metodo Start della query prima di eseguire il recupero:

// Create a query for all Person entities.
q := datastore.NewQuery("Person")

// If the application stored a cursor during a previous request, use it.
item, err := memcache.Get(ctx, "person_cursor")
if err == nil {
	cursor, err := datastore.DecodeCursor(string(item.Value))
	if err == nil {
		q = q.Start(cursor)
	}
}

// Iterate over the results.
t := q.Run(ctx)
for {
	var p Person
	_, err := t.Next(&p)
	if err == datastore.Done {
		break
	}
	if err != nil {
		log.Errorf(ctx, "fetching next Person: %v", err)
		break
	}
	// Do something with the Person p
}

// Get updated cursor and store it for next time.
if cursor, err := t.Cursor(); err == nil {
	memcache.Set(ctx, &memcache.Item{
		Key:   "person_cursor",
		Value: []byte(cursor.String()),
	})
}

Limitazioni dei cursori

I cursori sono soggetti alle seguenti limitazioni:

  • Un cursore può essere utilizzato solo dalla stessa applicazione che ha eseguito l'originale e solo per continuare la stessa query. Per utilizzare il cursore in una sequenza di recupero, devi ricostituire esattamente la query originale inclusi lo stesso tipo di entità, filtro predecessore, filtri di proprietà e ordini. Non è possibile recuperare i risultati utilizzando un cursore senza impostare la stessa query da cui è stato generato in origine.
  • I cursori non funzionano sempre come previsto con una query che utilizza una disuguaglianza un filtro o un ordinamento su una proprietà con più valori. La deduplicazione la logica per queste proprietà a più valori non persiste tra i recuperi, causando probabilmente la restituzione dello stesso risultato più di una volta.
  • Le nuove release di App Engine potrebbero modificare i dettagli di implementazione interna, invalidando i cursori che dipendono da questi. Se un'applicazione tenta di utilizzare un cursore non più valido, Datastore resi un errore.

Cursori e aggiornamenti dei dati

La posizione del cursore è definita come posizione nell'elenco dei risultati dopo il è stato restituito l'ultimo risultato. Un cursore non è una posizione relativa nell'elenco (non è un offset); è un indicatore a cui Datastore può saltare quando avvia una scansione dell'indice per i risultati. Se i risultati di una query cambiano tra gli utilizzi di un cursore, la query rileva solo le modifiche che si verificano nei risultati dopo il cursore. Se viene visualizzato un nuovo risultato prima della posizione del cursore per non verrà restituito quando vengono recuperati i risultati dopo il cursore. Analogamente, se un'entità non è più un risultato per una query, ma è stata visualizzata prima del cursore, i risultati visualizzati dopo il cursore non cambiano. Se l'ultimo risultato restituito viene rimosso dal set di risultati, il cursore sa ancora come trovare il risultato successivo.

Quando recuperi i risultati delle query, puoi utilizzare sia un cursore di inizio sia un cursore di fine per restituire un gruppo continuo di risultati da Datastore. Quando utilizzando un cursore di inizio e fine per recuperare i risultati, la garanzia che la dimensione dei risultati sarà la stessa di quando hai generato i cursori. Le entità possono essere aggiunte o eliminate da Datastore tra l'ora in cui vengono generati i cursori e il momento in cui vengono utilizzati in una query.

Passaggi successivi