2012-04-16 15 views
24

Was ist der beste/schnellste Weg zu prüfen, ob eine Entität in einem Google-App-Engine-Datenspeicher existiert? Momentan versuche ich, die Entität per Schlüssel zu erhalten und zu prüfen, ob get() einen Fehler zurückgibt.Prüfen, ob Entität im Google App Engine-Datenspeicher vorhanden ist.

Ich weiß nicht, wie eine Entität im Datenspeicher abgerufen wird. Gibt es einen schnelleren Weg, nur diese Prüfung durchzuführen?

+0

Wenn eine Entität per Schlüssel abgerufen wird, wird nie ein Fehler zurückgegeben, es wird None zurückgegeben. – aschmid00

+5

In Java löst 'get' eine Ausnahme aus, wenn die Entität nicht gefunden wurde: https://developers.google.com/appengine/docs/java/javadoc/com/google/appengine/api/datastore/DatastoreService#get(com.google .appengine.api.datastore.Key) –

+0

ok das wusste ich nicht. – aschmid00

Antwort

4

com.google.appengine.api wurde zugunsten des App Engine GCS-Clients abgelehnt.

Haben Sie überlegt, eine Abfrage zu verwenden? Guess-and-Check ist keine skalierbare Möglichkeit, eine Entität in einem Datenspeicher zu finden. Eine Abfrage kann erstellt werden Entitäten aus dem Datenspeicher abgerufen werden, die einen bestimmten Satz von Bedingungen erfüllen:

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

EDIT:

Was ist der Schlüssel nur abfragen? Nur-Schlüssel-Abfragen werden schneller ausgeführt als Abfragen, die vollständige Entitäten zurückgeben. Verwenden Sie die Query.setKeysOnly() - Methode, um nur die Schlüssel zurückzugeben.

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

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

+1

Die Zeitantwort für eine Abfrage ist besser zum Abrufen einer Entität? – Victor

+13

Nein, die Abfrage dauert immer länger und kostet mehr, daher glaube ich nicht, dass dies die richtige Antwort ist. –

+1

Die Kosten für eine Abfrage mit dem .setKeysOnly() - Filter haben tatsächlich die gleichen Kosten wie eine einzelne get-Operation (sowohl hinsichtlich der Bilanzierung als auch der effektiven Laufzeit, da dies hauptsächlich durch die Netzwerk-Roundtrip-Zeit bestimmt wird). Beachten Sie auch, dass die Abfrage für KEY_RESERVED_PROPERTY auf besondere Weise behandelt wird, da sie keinen eventuellen konsistenten Index als Abfrage für ein anderes Attribut verwendet, sondern stattdessen stark konsistent ist. Dies macht diese Antwort perfekt gültig, obwohl die Einsparungen durch Abrufen nur der Schlüssel für diese Art von Abfrage nicht angegeben sind. – Ext3h

3

Sie holen könnte ein List<Key> mit nur einem Key enthält, that method gibt ein Map<Key, Entity>, die Sie überprüfen können, ob es einen tatsächlichen Wert oder null enthält, zum Beispiel:

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

im allgemeinen obwohl ich denke, es einfacher sein würde, die get() in einem try/catch zu wickeln, diezurückwenn der EntityNotFoundException gefangen ist.

+0

Warum ist das am besten, wenn Sie nur get (Key) verwenden? – Victor

+0

Es scheint mir "korrekter" zu sein, wenn Sie nur nach einem Schlüssel suchen - aber es ist ganz persönliche Präferenz und das liegt an Ihnen. –

+0

Ich frage besser basierend auf der Reaktionszeit – Victor

6

Was Sie vorgeschlagen haben, wäre in der Tat der schnellste Weg zu wissen, ob Ihre Entität existiert. Die einzige Sache, die Sie verlangsamt, ist die Zeit, die benötigt wird, um Ihre Entität zu holen und zu deserialisieren. Wenn Ihre Entität groß ist, kann dies Sie verlangsamen.

Wenn diese Aktion (Existenzprüfung) für Sie ein großer Engpass ist und Sie große Entitäten haben, möchten Sie vielleicht Ihr eigenes System zur Überprüfung mit zwei Entitäten rollen - zuerst würden Sie Ihre vorhandene Entität mit Daten und eine zweite Entität, die entweder die Referenz auf die reale Entität speichert oder eine leere Entität, bei der der Schlüssel nur eine Variation des ursprünglichen Entitätsschlüssels ist, den Sie berechnen können. Sie können mit der zweiten Entität schnell auf Vorhandensein prüfen und dann die erste Entität nur dann holen, wenn die Daten erforderlich sind.

Der bessere Weg wäre meiner Meinung nach nur, Ihre Schlüssel so zu entwerfen, dass Sie wissen, dass es keine Duplikate geben wird, oder dass Ihre Operationen idempotent sind, so dass selbst eine alte Entität überschrieben würde.

+0

Ich glaube nicht, dass es eine Möglichkeit gibt, diese Prüfung zu vermeiden, wenn mehrere Prozesse parallel laufen. Die einzige Möglichkeit, keine Duplikate sicherzustellen, besteht darin, eine Transaktion zu verwenden: Überprüfen Sie, ob eine Entität bereits vorhanden ist. Wenn nicht, erstellen Sie eine neue Entität. –

+0

Sie haben meine Antwort wahrscheinlich nicht verstanden. Ich sagte ziemlich genau dasselbe. Und dann habe ich eine Optimierung hinzugefügt, wenn Sie große Entitäten haben und die große Entität nicht deserialisieren möchten. Sie könnten eine zweite kleine Entität haben, die nach Existenz sucht, so dass sie viel schneller zurückkehrt als die große Entität. Aber Sie schreiben, Sie müssten diese beiden Entitäten in einer Transaktion schreiben. – dragonx

Verwandte Themen