-
Notifications
You must be signed in to change notification settings - Fork 64
queries
Not applicable to this runtime.
A Datastore query retrieves entities from Datastore that meet a specified set of conditions.
A typical query includes the following:
- An entity kind to which the query applies
- Optional filters based on the entities' property values, keys, and ancestors
- Optional sort orders to sequence the results
When executed, a query retrieves all entities of the given kind that satisfy all of the given filters, sorted in the specified order. Queries execute as read-only.
This page describes the structure and kinds of queries used within App Engine to retrieve data from Datastore.
A query's filters set constraints on the properties, keys, and ancestors of the entities to be retrieved.
A property filter specifies
<li>A property name</li>
<li>A comparison operator</li>
<li>A property value</li>
For example:
The property value must be supplied by the application; it cannot refer to or be calculated in terms of other properties. An entity satisfies the filter if it has a property of the given name whose value compares to the value specified in the filter in the manner described by the comparison operator.
The comparison operator can be any of the following (defined as enumerated
constants in the nested class
Query.FilterOperator):
<tr>
<th>Operator</th>
<th>Meaning</th>
</tr>
<tr>
<td>`EQUAL`</td>
<td>Equal to</td>
</tr>
<tr>
<td>`LESS_THAN`</td>
<td>Less than</td>
</tr>
<tr>
<td>`LESS_THAN_OR_EQUAL`</td>
<td>Less than or equal to</td>
</tr>
<tr>
<td>`GREATER_THAN`</td>
<td>Greater than</td>
</tr>
<tr>
<td>`GREATER_THAN_OR_EQUAL`</td>
<td>Greater than or equal to</td>
</tr>
<tr>
<th>Operator</th>
<th>Meaning</th>
</tr>
<tr>
<td>`EQUAL`</td>
<td>Equal to</td>
</tr>
<tr>
<td>`LESS_THAN`</td>
<td>Less than</td>
</tr>
<tr>
<td>`LESS_THAN_OR_EQUAL`</td>
<td>Less than or equal to</td>
</tr>
<tr>
<td>`GREATER_THAN`</td>
<td>Greater than</td>
</tr>
<tr>
<td>`GREATER_THAN_OR_EQUAL`</td>
<td>Greater than or equal to</td>
</tr>
<tr>
<td>`NOT_EQUAL`</td>
<td> Not equal to</td>
</tr>
<tr>
<td>`IN`</td>
<td> Member of (equal to any of the values in a specified list)</td>
</tr>
The NOT_EQUAL operator actually performs two queries: one in which all other
filters are unchanged and the NOT_EQUAL filter is replaced with a LESS_THAN
filter, and one where it is replaced with a GREATER_THAN filter. The results
are then merged, in order. A query can have no more than one NOT_EQUAL filter,
and a query that has one cannot have any other inequality filters.
The IN operator also performs multiple queries: one for each item in the
specified list, with all other filters unchanged and the IN filter replaced
with an EQUAL filter. The results are merged in order of the items in the
list. If a query has more than one IN filter, it is performed as multiple
queries, one for each possible combination of values in the IN lists.
A single query containing NOT_EQUAL or IN operators is limited to a maximum
of 30 subqueries.
For more information about how `NOT_EQUAL` and `IN` queries translate to multiple queries in a JDO/JPA framework, see the article Queries with != and IN filters.
To filter on the value of an entity's key, use the special property
Entity.KEY_RESERVED_PROPERTY__key__:
View QueriesTest.java on GitHub (region:
key_filter_example)
Ascending sorts on Entity.KEY_RESERVED_PROPERTY are also supported.
When comparing for inequality, keys are ordered by the following criteria, in order:
- Ancestor path
- Entity kind
- Identifier (key name or numeric ID)
Elements of the ancestor path are compared similarly: by kind (string), then by key name or numeric ID. Kinds and key names are strings and are ordered by byte value; numeric IDs are integers and are ordered numerically. If entities with the same parent and kind use a mix of key name strings and numeric IDs, those with numeric IDs precede those with key names.
Queries on keys use indexes just like queries on properties and require custom indexes in the same cases, with a couple of exceptions: inequality filters or an ascending sort order on the key do not require a custom index, but a descending sort order on the key does. As with all queries, the development web server creates appropriate entries in the index configuration file when a query that needs a custom index is tested.
You can filter your Datastore queries to a specified ancestor so that the results returned will include only entities descended from that ancestor:
View QueriesTest.java on GitHub (region:
ancestor_filter_example)
Caution: Passing null as the ancestor key does not query for root entities
(those without ancestors). This type of query is not currently supported and
will return an error.
Some specific types of query deserve special mention:
A query with no kind and no ancestor filter retrieves all of the entities of an
application from Datastore. This includes entities created and managed by other
App Engine features, such as statistics entities and Blobstore
metadata
entitiesBlobstore
metadata
entities
(if any). Such kindless queries cannot include filters or sort orders on
property values. They can, however, filter on entity keys by specifying
Entity.KEY_RESERVED_PROPERTY__key__
as the property name:
View QueriesTest.java on GitHub (region:
kindless_query_example)
A query with an ancestor filter limits its results to the specified entity and its descendants:
View QueriesTest.java on GitHub (region:
ancestor_query_example)
Note: Setting an ancestor filter allows for strongly consistent queries. Queries without an ancestor filter only return eventually consistent results.
A kindless query that includes an ancestor filter will retrieve the specified ancestor and all of its descendants, regardless of kind. This type of query does not require custom indexes. Like all kindless queries, it cannot include filters or sort orders on property values, but can filter on the entity's key:
View QueriesTest.java on GitHub (region:
kindless_ancestor_key_query_example)
The following example illustrates how to retrieve all entities descended from a given ancestor:
View QueriesTest.java on GitHub (region:
kindless_ancestor_query_example)
A keys-only query returns just the keys of the result entities instead of the entities themselves, at lower latency and cost than retrieving entire entities:
It is often more economical to do a keys-only query first, and then fetch a subset of entities from the results, rather than executing a general query which may fetch more entities than you actually need.
Note that a keys-only query can return more than 1000 results, but GetAll can
only retrieve 1000 keys at a time, and will fail with an error if called on a
larger result. Therefore, we recommend adding a limit of 1000 keys to the query.
Sometimes all you really need from the results of a query are the values of a few specific properties. In such cases, you can use a projection query to retrieve just the properties you're actually interested in, at lower latency and cost than retrieving the entire entity; see the Projection Queries page for details.
A query sort order specifies
<li>A property name</li>
<li>A sort direction (ascending or descending)</li>
In Go, descending sort order is denoted by a hyphen (-) preceding the property
name; omitting the hyphen specifies ascending order by default. For example:
For example:
In Python, descending sort order is denoted by a hyphen (-) preceding the
property name; omitting the hyphen specifies ascending order by default. For
example:
If a query includes multiple sort orders, they are applied in the sequence specified. The following example sorts first by ascending last name and then by descending height:
If no sort orders are specified, the results are returned in the order they are retrieved from Datastore.
**Note:** Because of the way Datastore executes queries, if a query specifies inequality filters on a property and sort orders on other properties, the property used in the inequality filters must be ordered before the other properties.
Every Datastore query computes its results using one or more indexes, which contain entity keys in a sequence specified by the index's properties and, optionally, the entity's ancestors. The indexes are updated incrementally to reflect any changes the application makes to its entities, so that the correct results of all queries are available with no further computation needed.
App Engine predefines a simple index on each property of an entity. An App
Engine application can define further custom indexes in an index configuration
file named
datastore-indexes.xml, which is generated in your application's
/war/WEB-INF/appengine-generated directory index.yaml. The development
server automatically adds suggestions to this file as it encounters queries that
cannot be executed with the existing indexes. You can tune indexes manually by
editing the file before uploading the application.
The Go Datastore API provides a Query type for preparing and executing queries.
The low-level Java Datastore API provides class
Query
for constructing queries and the
PreparedQuery
interface for retrieving entities from Datastore:
View QueriesTest.java on GitHub (region:
interface_1)
Notice the use of
FilterPredicate
and
CompositeFilter
to construct filters. If you're setting only one filter on a query, you can just
use FilterPredicate by itself:
View QueriesTest.java on GitHub (region:
interface_2)
However, if you want to set more than one filter on a query, you must use
CompositeFilter, which requires at least two filters. The example above uses
the shortcut helper CompositeFilterOperator.and; the following example shows
one way of constructing a composite OR filter:
View QueriesTest.java on GitHub (region:
interface_3)
Caution: Note that using an OR filter will cause multiple queries to be executed against the underlying Datastore.
Note: The properties being filtered on must have a corresponding predefined
index which can be defined in your index configuration
file
(datastore-indexes.xml``index.yaml).
- Learn how to specify what a query returns and further control query results. * Learn the common restrictions for queries on Datastore. * Learn about query cursors, which allow an application to retrieve a query's results in convenient batches. * Understand data consistency and how data consistency works with different types of queries on Datastore.
We recommend using the NDB Client Library for Datastore, which has several benefits compared to this client library, such as automatic entity caching via the Memcache API. If you are currently using the older DB Client Library, see the DB to NDB Migration Guide.