2012-04-16 9 views
24

Qual è il modo migliore/più veloce per verificare se esiste un'entità in un archivio dati google-app-engine? Per ora sto cercando di ottenere l'entità per chiave e controllando se get() restituisce un errore.Verifica dell'esistenza dell'entità nel datastore del motore dell'app google.

Non conosco il processo di acquisizione di un'entità sul datastore. C'è un modo più veloce per fare solo questo controllo?

+0

ottenere un'entità per chiave non restituirà mai un errore, restituisce Nessuno. – aschmid00

+5

In java 'get' genera un'eccezione quando l'entità non viene trovata: https://developers.google.com/appengine/docs/java/javadoc/com/google/appengine/api/datastore/DatastoreService#get(com.google .appengine.api.datastore.Key) –

+0

ok non lo sapevo. – aschmid00

risposta

4

com.google.appengine.api è stato dichiarato obsoleto a favore del client GCS di App Engine.

Hai mai pensato di utilizzare una query? Guess-and-check non è un modo scalabile per scoprire l'esistenza di un'entità in un archivio dati. Una query può essere creata per recuperare le entità del datastore che soddisfano una serie di condizioni specificato:

https://developers.google.com/appengine/docs/java/datastore/queries

EDIT:

E la chiave di sola tua ricerca? Le query solo chiave vengono eseguite più rapidamente delle query che restituiscono entità complete. Per restituire solo le chiavi, utilizzare il metodo Query.setKeysOnly().

new Query("Kind").addFilter(Entity.KEY_RESERVED_PROPERTY, FilterOperator.EQUAL, key).setKeysOnly(); 

Fonte: [1]: http://groups.google.com/group/google-appengine-java/browse_thread/thread/b1d1bb69f0635d46/0e2ba938fad3a543?pli=1

+1

La risposta temporale per eseguire una query è migliore per il recupero di un'entità? – Victor

+13

No, la query richiederà sempre più tempo e costa di più, quindi non penso che questa sia la risposta giusta. –

+1

Il costo per una query con il filtro .setKeysOnly() ha in realtà lo stesso costo di un'operazione di ottenimento singola (sia in termini di contabilità che di runtime efficace poiché questo è determinato principalmente dal tempo di andata e ritorno della rete). Si noti inoltre che la query per KEY_RESERVED_PROPERTY viene trattata in modo speciale in quanto non utilizza un eventuale indice coerente come una query per qualsiasi altro attributo, ma è invece fortemente coerente. Questo rende questa risposta perfettamente valida, sebbene i risparmi tramite il recupero delle chiavi non siano specificati per questo tipo di query. – Ext3h

3

Si potrebbe prendere con un List<Key> contenente un solo Key, that method restituisce un Map<Key, Entity> quale si può verificare se contiene un valore effettivo o null, ad esempio:

Entity e = datastoreService.get(Arrays.asList(key)).get(key); 

in generale, anche se penso che sarebbe più facile per avvolgere il get() in un try/catch che restituisce null se viene rilevato lo EntityNotFoundException.

+0

Perché questo è meglio usando solo get (chiave)? – Victor

+0

Mi sembra più "corretto" per me se stai solo recuperando una sola chiave, ma è una preferenza del tutto personale, e fino a te. –

+0

Sto chiedendo meglio in base al tempo di risposta – Victor

6

Quello che hai proposto sarebbe davvero il modo più veloce per sapere se la tua entità esiste. L'unica cosa che ti rallenta è il tempo necessario per recuperare e deserializzare la tua entità. Se la tua entità è grande, questo può rallentare.

SE questa azione (verifica dell'esistenza) è un collo di bottiglia principale per te e hai grandi entità, potresti voler eseguire il rollover del tuo sistema di controllo usando due entità - prima avresti la tua entità esistente con i dati, e una seconda entità che memorizza il riferimento all'entità reale o forse un'entità vuota in cui la chiave è solo una variazione della chiave dell'entità originale che è possibile calcolare. È possibile verificare rapidamente l'esistenza utilizzando la seconda entità e quindi recuperare la prima entità solo se i dati sono necessari.

Il modo migliore in cui penso sarebbe solo quello di progettare le chiavi in ​​modo che sappiano che non ci sarebbero duplicati o che le operazioni sono idempotenti, così che anche se una vecchia entità venisse sovrascritta, non avrebbe importanza.

+0

Non penso che ci sia un modo per evitare questo controllo quando diversi processi vengono eseguiti in parallelo. L'unico modo per assicurarsi che non ci siano duplicati è usare una transazione: controlla se esiste già un'entità, altrimenti crea una nuova entità. –

+0

Probabilmente non hai capito la mia risposta. Ho detto più o meno la stessa cosa. E poi, ho aggiunto un'ottimizzazione nel caso in cui si abbiano entità grandi e non si voglia deserializzare la grande entità. Potresti avere una seconda piccola entità per verificare l'esistenza in modo che ritorni molto più velocemente rispetto al recupero della grande entità. Ma tu scrivi, dovresti scrivere quelle due entità in una transazione. – dragonx

Problemi correlati