Beschränkungen bei Abfragen

Auf dieser Seite werden die Beschränkungen behandelt, die für Datastore-Abfragen von Google App Engine aus gelten. Die folgende Liste enthält gängige Einschränkungen, auf die Sie bei der Entwicklung von Datastore treffen werden.

Entitäten, bei denen ein in der Abfrage benanntes Attribut fehlt, werden ignoriert

Entitäten desselben Typs haben nicht unbedingt dieselben Attribute. Damit eine Entität als Abfrageergebnis genutzt werden kann, muss sie einen Wert (kann null sein) für jedes Attribut haben, das in den Filtern und Sortierfolgen der Abfrage benannt wird. Wenn die Entität diese Voraussetzung nicht erfüllt, wird sie nicht in die Indexe für die Ausführung der Abfrage aufgenommen. Sie ist dann auch nicht in den Ergebnissen enthalten.

Filterung nach nicht indexierten Attributen gibt keine Ergebnisse zurück

Eine Abfrage kann keine Attributwerte finden, die nicht indexiert sind, und kann nicht nach derartigen Attributen sortieren. Eine detaillierte Erläuterung von nicht indexierten Attributen finden Sie auf der Seite Nicht indexierte Attribute.

Ungleichheitsfilter sind auf maximal ein Attribut begrenzt

Damit nicht der gesamte Index gescannt werden muss, wird bei diesem Abfrageverfahren davon ausgegangen, dass alle potenziellen Ergebnisse einer Abfrage in dem Index nebeneinanderstehen. Aus diesem Grund dürfen in einer einzelnen Abfrage keine Ungleichheitsvergleiche (<, <=, >, >=, !=) für mehr als ein Attribut in allen ihren Filtern verwendet werden. Beispiel: Die folgende Abfrage ist gültig, weil beide Ungleichheitsfilter auf dasselbe Attribut angewendet werden:

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

Diese Abfrage ist dagegen ungültig, da sie Ungleichheitsfilter für zwei verschiedene Attribute verwendet:

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

In einer Abfrage können Gleichheitsfilter (=) für unterschiedliche Attribute mit einem oder mehreren Ungleichheitsfiltern für ein einzelnes Attribut kombiniert werden. Daher ist die folgende Abfrage gültig:

SELECT * FROM Person WHERE last_name = :target_last_name AND city = :target_city AND birth_year >= :min_birth_year AND birth_year <= :max_birth_year

Reihenfolge der Abfrageergebnisse ist undefiniert, wenn keine Sortierfolge angegeben wird

Wenn eine Abfrage keine Sortierfolge angibt, werden die Ergebnisse in der Reihenfolge zurückgegeben, in der sie abgerufen werden. Im Laufe der Datastore-Implementierung (oder wenn sich die Indexe einer Anwendung ändern) kann sich diese Reihenfolge ändern. Müssen die Abfrageergebnisse bei Ihrer Anwendung eine bestimmte Reihenfolge aufweisen, müssen Sie diese Sortierfolge deshalb explizit in der Abfrage angeben.

Sortierfolgen werden bei Attributen mit Gleichheitsfiltern ignoriert

Abfragen, die einen Gleichheitsfilter für ein bestimmtes Attribut enthalten, ignorieren jede für dieses Attribut angegebene Sortierfolge. Dies ist eine einfache Optimierung, mit der eine unnötige Verarbeitung bei einzelwertigen Attributen vermieden wird, weil alle Ergebnisse denselben Wert für das Attribut haben und somit keine weitere Sortierung erforderlich ist. Mehrwertige Attribute hingegen können zusätzliche Werte neben dem Wert haben, der mit dem Gleichheitsfilter übereinstimmt. Weil dieser Anwendungsfall selten ist, die Anwendung der Sortierfolge teuer wäre und zusätzliche Indexe erfordern würde, ignoriert der Datastore-Abfrageplaner die Sortierfolge einfach, selbst bei einem Fall mit mehreren Werten. Dies kann dazu führen, dass Abfrageergebnisse in einer anderen Reihenfolge zurückgegeben werden, als die Sortierfolge scheinbar impliziert.

In Ungleichheitsfiltern verwendete Attribute müssen zuerst sortiert werden

Zum Abrufen aller Ergebnisse, die mit einem Ungleichheitsfilter übereinstimmen, scannt eine Abfrage den Index auf die erste Zeile, die mit dem Filter übereinstimmt, und scannt dann weiter, bis eine nicht übereinstimmende Zeile gefunden wird. Damit die aufeinanderfolgenden Zeilen die vollständige Ergebnismenge bilden, müssen sie vor allen anderen Attributen sortiert werden, und zwar nach dem Attribut, das in dem Ungleichheitsfilter verwendet wird. Wenn eine Abfrage also einen oder mehrere Ungleichheitsfilter zusammen mit einer oder mehreren Sortierfolgen angibt, muss sich die erste Sortierfolge auf dasselbe Attribut beziehen, das in den Ungleichheitsfiltern angegeben wird. Die folgende Abfrage ist eine gültig:

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

Diese Abfrage ist ungültig, da sie nicht nach dem Attribut sortiert, das in dem Ungleichheitsfilter verwendet wird:

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

Ebenso ist diese Abfrage nicht gültig, weil das in dem Ungleichheitsfilter verwendete Attribut nicht das erste sortierte Attribut ist:

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

Das Verhalten von Attributen mit mehreren Werten kann überraschend sein

Aufgrund der Art der Indexierung können Entitäten mit mehreren Werten für dasselbe Attribut gelegentlich auf unerwartete und überraschende Weise mit Abfragefiltern und Sortierfolgen interagieren.

Wenn eine Abfrage mehrere Ungleichheitsfilter für ein bestimmtes Attribut enthält, stimmt eine Entität nur dann mit der Abfrage überein, wenn mindestens einer der individuellen Werte des Attributs alle Filter erfüllt. Wenn beispielsweise eine Entität vom Typ Widget die Werte 1 und 2 für das Attribut x hat, stimmt sie nicht mit der Abfrage überein:

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

Jeder x-Wert der Entität erfüllt einen der Filter, aber keiner der Einzelwerte erfüllt beide Filter. Beachten Sie, dass dies nicht für Gleichheitsfilter gilt. Beispielsweise erfüllt dieselbe Entität die folgende Abfrage:

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

Dabei erfüllt keiner der individuellen x-Werte der Entität beide Filterbedingungen.

Der Ungleichoperator (!=) fungiert als Test vom Typ "Wert ist anders als". So entspricht zum Beispiel die Abfrage

SELECT * FROM Widget WHERE x != 1

jede Widget-Entität mit einem anderen x-Wert als 1.

Genauso ist die Sortierfolge für mehrwertige Attribute ungewöhnlich. Weil derartige Attribute einmal im Index für jeden eindeutigen Wert auftreten, bestimmt der erste Wert im Index die Sortierreihenfolge der Entität.

  • Wenn die Abfrageergebnisse aufsteigend sortiert werden, wird der kleinste Wert des Attributs für die Sortierung verwendet.
  • Wenn die Ergebnisse in absteigender Reihenfolge sortiert werden, wird der größte Wert für die Sortierung verwendet.
  • Andere Werte und auch die Anzahl der Werte haben keinen Einfluss auf die Sortierfolge.

Dies hat die ungewöhnliche Folge, dass eine Entität mit den Attributwerten 1 und 9 in aufsteigender und absteigender Reihenfolge vor einer Entität mit den Werten 4, 5, 6 und 7 platziert ist.

Abfragen innerhalb von Transaktionen müssen Ancestor-Filter enthalten

Datastore-Transaktionen werden nur für Entitäten ausgeführt, die zur selben Entitätengruppe gehören (Nachfolgeentitäten eines gemeinsamen Ancestors). Wegen dieser Beschränkung müssen alle innerhalb einer Transaktion ausgeführten Abfragen einen Ancestor-Filter enthalten, der einen Ancestor in derselben Entitätengruppe wie die anderen Vorgänge in der Transaktion angibt.