2009/05/10

Queries and Indexes

つづき。一昨日ダウンロードした内容と今の原本のHTMLが微妙にちがってたのでずれてるかも。翻訳エディタ使うかなぁ。

Queries and Indexes

Every datastore query uses an index, a table that contains the results for the query in the desired order. An App Engine application defines its indexes in a configuration file named datastore-indexes.xml. The development web server can automatically generate suggestions for this file as it encounters queries that do not yet have indexes configured.

各Datastoreクエリは、希望の順でクエリの結果を含むテーブルであるインデックスを使います。App Engineアプリケーションはdatastore-indexes.xmlという名前の設定ファイルにインデックスを定義します。開発Webサーバは設定されていないインデックスのクエリに遭遇すると、インデックスを提案し、そのファイルに自動的に書き込みます。

The index-based query mechanism supports most common kinds of queries, but it does not support some queries you may be used to from other database technologies. Restrictions on queries, and their explanations, are described below.

インデックスベースのクエリメカニズムは、ほとんどの一般的な種類のクエリをサポートしています。しかし、他のデータベーステクノロジで使ってきたようないくつかのクエリはサポートしていません。クエリの制限については後述します。

Introducing Queries

A query retrieves entities from the datastore that meet a set of conditions. The query specifies an entity kind, zero or more conditions based on entity property values (sometimes called "filters"), and zero or more sort order descriptions. When the query is executed, it fetches all entities of the given kind that meet all of the given conditions, sorted in the order described.

クエリはコンディションのセットに合致するエンティティをDatastoreから抽出します。このクエリはエンティティの種類、0以上エンティティのプロパティの値に基づくコンディション(「フィルタ」と呼ばれます)と、ゼロ以上のソート順を指定します。クエリが実行されると、与えられた種類と、コンディションに合致するすべてのエンティティを取得し、指定された順にソートします。

A query can also return just the keys of the result entities instead of the entities themselves.

また、クエリはエンティティ自身のかわりに、結果のエンティティの「キー」を返すこともできます。

JDO can perform queries for entities that meet certain criteria. You can also use a JDO Extent to represent the collection of every entity of a kind (every stored object of a class).

JDOは指定されたクライテリアに合致するエンティティのクエリを実行します。また、ある種類の全てのエンティティ(あるクラスの全ての保存されているオブジェクト)を表現するJDO Extentを使用することができます。

Queries with JDOQL

JDO includes a query language for retrieving objects that meet a set of criteria. This language, called JDOQL, refers to JDO data classes and fields directly, and includes type checking for query parameters and results. JDOQL is similar to SQL, but is more appropriate for object-oriented databases like the App Engine datastore. (The App Engine datastore does not support SQL queries with the JDO interface.)

JDOは指定されたクライテリアに合致するエンティティのクエリを実行します。また、ある種類の全てのエンティティ(あるクラスの全ての保存されているオブジェクト)を表現するJDO Extentを使用することができます。

The query API supports several calling styles. You can specify a complete query in a string, using the JDOQL string syntax. You can also specify some or all parts of the query by calling methods on the query object.

このクエリAPIはいくつかの呼び出しスタイルをサポートしています。JDOQL文字列の文法をつかった完全なクエリを指定することができます。また、クエリのいくつかまたは全ての部分を、クエリオブジェクトのメソッドを呼び出すことによって指定することもできます。

Here is a simple example of a query using the method style of calling, with one filter and one sort order, using parameter substitution for the value used in the filter. The Query object's execute() method is called with the values to substitute in the query, in the order they are declared.

これはメソッドスタイルの呼び出しを使ったクエリの例です。1つのフィルタと、1つのソート順を指定し、フィルタのパラメータの代入を行っています。Queryオブジェクトのexecute()メソッドが、前に宣言した代入値とともに呼ばれます。

import java.util.List;
import javax.jdo.Query;

// ...

    Query query = pm.newQuery(Employee.class);
    query.setFilter("lastName == lastNameParam");
    query.setOrdering("hireDate desc");
    query.declareParameters("String lastNameParam");

    try {
        List<Employee> results = (List<Employee>) query.execute("Smith");
        if (results.iterator().hasNext()) {
            for (Employee e : results) {
                // ...
            }
        } else {
            // ... no results ...
        }
    } finally {
        query.closeAll();
    }

Here is the same query using the string syntax:

これは同じクエリを文字列文法を使って記載しています。

    Query query = pm.newQuery("select from Employee " +
                              "where lastName == lastNameParam " +
                              "order by hireDate desc " +
                              "parameters String lastNameParam")

    List<Employee> results = (List<Employee>) query.execute("Smith");

You can mix these styles of defining the query. For example:

これらのスタイルを混ぜてクエリを定義することもできます。

    Query query = pm.newQuery(Employee.class,
                              "lastName == lastNameParam order by hireDate desc");
    query.declareParameters("String lastNameParam");

    List<Employee> results = (List<Employee>) query.execute("Smith");

You can reuse a single Query instance with different values substituted for the parameters by calling the execute() method multiple times. Each call performs the query and returns the results as a collection.

一つのQueryインスタンスをことなるパラメータをexecute()メソッドに渡して何度も呼ぶことで再利用することができます。各呼び出しはクエリを実行して、コレクションとして結果を返します。

The JDOQL string syntax supports value literals within the string for string values and numeric values. Surround strings in either single-quotes (') or double-quotes ("). All other value types must use parameter substitution. Here is an example using a string literal value:

JDOQL文字列文法は文字列と数値のリテラル値をサポートしています。シングルクォートかダブルクォートで文字列を囲んでください。全てのほかの値の型はパラメータ代入を使う必要があります。次は文字列リテラルを使った例です。

    Query query = pm.newQuery(Employee.class,
                              "lastName == 'Smith' order by hireDate desc");

Query Filters

A filter specifies a field name, an operator, and a value. The value must be provided by the app; it cannot refer to another property, or be calculated in terms of other properties. The operator can be any of the following: < <= == >= >

フィルタは、フィールド名、演算子、そして値を指定します。その値はアプリケーションによって提供されなければならず、他のプロパティの値を参照や、他のプロパティに関して計算されることができません。この演算子はつぎのいずれかが使えます:< <= == >= >

Note: The Java datastore interface does not support the != and IN filter operators that are implemented in the Python datastore interface. (In the Python interface, these operators are implemented in the client-side libraries as multiple datastore queries; they are not features of the datastore itself.)

注:Java Datastoreインターフェースでは、Pythonデータストアインターフェースで実装している!=とINフィルタ演算子をサポートしていません。(Pythonインターフェースでは、これらの演算子はクライアントサイドライブラリとして複数のデータストアクエリで実装しています。これらはDatastore自身の機能ではありません)

The subject of a filter can be any object field, including the primary key and the entity group parent (see Transactions).

フィルタの対象には、オブジェクトのフィールド、プライマリキー、エンティティグループの親を含むことができます。(Transactionsを参照)

An entity must match all filters to be a result. In the JDOQL string syntax, multiple filters are specified separated by && (logical "and"). Other logical combinations of filters (logical "or", "not") are not supported.

結果のエンティティは、全てのフィルタにマッチしなければなりません。JDOQLの文字列文法では、複数のフィルタは&& (論理"and")で分割して指定することができます。他の論理演算(論理 "or", "not")はサポートされていません。

Due to the way the App Engine datastore executes queries, a single query cannot use inequality filters (< <= >= >) on more than one property. Multiple inequality filters on the same property (such as querying for a range of values) are permitted. See Restrictions on Queries.

App Engine datastoreがクエリを実行するとき、単一のクエリは一つ以上のプロパティに不等号フィルタ(< <= >= >)を使うことができません。複数の不等号フィルタを同じプロパティ(値の範囲のクエリのような)は許可されています。Restrictions on Queriesを参照してください。

    query.setFilter("lastName == 'Smith' && hireDate > hireDateMinimum");
    query.declareParameters("Date hireDateMinimum");

Query Sort Orders

A sort order specifies a property and a direction, either ascending or descending. The results are returned sorted by the given orders, in the order they were specified. If no sort orders are specified for the query, the results are ordered by their entity keys.

ソート順は、プロパティと方向、昇順か降順を指定します。結果は与えられた順で指定した順でソートされて返されます。もしソート順を指定しなかった場合、エンティティのキー順となります。

Due to the way the App Engine datastore executes queries, if a query specifies inequality filters on a property and sort orders on other properties, the property used with the inequality filters must be ordered before the other properties. See Restrictions on Queries.

App Engine datastoreでクエリを実行するとき、不等号フィルタとソート順を他のプロパティに指定すると、不等号フィルタで使われたプロパティは、他のプロパティの前にソートされなければなりません。Restrictions on Queriesを参照してください。

    query.setOrdering("hireDate desc, firstName asc");

Query Ranges

A query can specify a range of results to be returned to the application. The range specifies which result in the complete result set should be the first one returned, and which should be the last, using numeric indexes, starting with 0 for the first result. For example, a range of 5, 10 returns the 6th, 7th, 8th, 9th and 10th results.

クエリは、アプリケーションに返す結果の範囲を指定することができます。範囲は完全な結果セットからどの範囲の結果かの最初と最後を、最初の結果を0とした数字のインデックスで指定することができます。例えば、5から10の範囲は、6~10番目の結果を返します。

The starting offset has implications for performance: the datastore must retrieve and then discard all results prior to the starting offset. For example, a query with a range of 5, 10 fetches 10 results from the datastore, then discards the first 5 and returns the remaining 5 to the application.

パフォーマンスのため、開始オフセットは明示的に指定します。Datastoreは開始オフセットの前の全ての結果を抽出し排除しなければなりません。例えば、5, 10の範囲を持つクエリは10の結果をDatastoreから抽出し、最初の5個を破棄し、残りの5個をアプリケーションに返します。

    query.setRange(5, 10);

Extents

A JDO Extent represents every object in the datastore of a particular class..

JDO Extentは、Datastore中のある特定のクラスのすべてのオブジェクトをあらわします。

You start an Extent using the PersistenceManager's getExtent() method, passing it the data class. The Extent class implements the Iterable interface for accessing results. When you are done accessing results, you call the closeAll() method.

PersistenceManagerの getExtent()メソッドにデータクラスを渡して使うことによりExtentを開始できます。ExtentクラスはIterableインタフェースを実装しており、結果にアクセスすることができます。結果にアクセスが終わったら、 closeAll()メソッドを呼んでください。

The following example iterates over every Employee object in the datastore:

次にDatastore中の全てのEmployeeオブジェクトを繰り返す例をしめします。

import java.util.Iterator;
import javax.jdo.Extent;

// ...

    Extent extent = pm.getExtent(Employee.class, false);
    for (Employee e : extent) {
        // ...
    }
    extent.closeAll();

An extent retrieves results in batches, and can exceed the 1,000-result limit that applies to queries.

Extentはバッチで結果を抽出し、クエリに適用される1000件までという結果の制限を超えることができます。

Introducing Indexes

The App Engine datastore maintains an index for every query an application intends to make. As the application makes changes to datastore entities, the datastore updates the indexes with the correct results. When the application executes a query, the datastore fetches the results directly from the corresponding index.

App Engine datastoreはクエリごとにアプリケーションの意図に合わせてインデックスをメンテナンスします。アプリケーションがDatastoreのエンティティを変更すると、Datastoreは収集した結果でインデックスを更新します。アプリケーションがクエリを実行したとき、Datastoreは対応するインデックスから直接結果を収集します。

An application has an index for each combination of kind, filter property and operator, and sort order used in a query. Consider the example query, stated in JDOQL:

種類と、フィルタのプロパティと演算子、そしてソート順を使用したクエリを結合したインデックスをアプリケーションは持っています。次のJDOQLクエリの例を考えて見ましょう

select from Person where lastName == "Smith"
                      && height < 72
                order by height desc

The index for this query is a table of keys for entities of the kind Person, with columns for the values of the height and lastName properties. The index is sorted by height in descending order.

このクエリのインデックスはheightとlastNameというプロパティの値のカラムを持つ、Personという種類のエンティティのキーのテーブルです。このインデックスは降順のheightのソートを持っています。

Two queries of the same form but with different filter values use the same index. For example, the following query uses the same index as the query above:

同じ形で、異なるフィルタの値の2つのクエリは同じインデックスを使用します。例えば、次のくえりは上記のクエリと同じインデックスを使用します。

select from Person where lastName == "Jones"
                      && height < 64
                order by height desc

The datastore executes a query using the following steps:

Datastoreは次の手順でクエリを実行します。

  1. The datastore identifies the index that corresponds with the query's kind, filter properties, filter operators, and sort orders.
  2. The datastore starts scanning the index at the first entity that meets all of the filter conditions using the query's filter values.
  3. The datastore continues to scan the index, returning each entity, until it finds the next entity that does not meet the filter conditions, until it reaches the end of the index, or until it has collected the maximum number of results requested by the query.
  1. Datastoreはクエリの種類、フィルタのプロパティ、フィルタの演算子、ソート順と対応するインデックスを識別します。
  2. クエリのフィルタ値を使って全てのフィルタのコンディションに合致する最初のエントリをインデックスから検索します。
  3. フィルタの条件に合致しない次のエンティティが見つかる、インデックスの末尾に達する、クエリの要求する最大の結果数に達するのいずれかが発生するまで、インデックスをスキャンし続けエンティティを返します。

An index table contains columns for every property used in a filter or sort order. The rows are sorted by the following aspects, in order:

インデックステーブルはフィルタもしくはソート順で使用する全てのプロパティのカラムを保持しています。行は次の側面と順でソートされています。

  • ancestors
  • property values used in equality filters
  • property values used in inequality filters
  • property values used in sort orders
  • 祖先
  • 等号フィルタで使用するプロパティの値
  • 不等号フィルタで使用するプロパティの値
  • ソート順で使用するプロパティの値

This puts all results for every possible query that uses this index in consecutive rows in the table.

このテーブルの連続する行の、インデックスで使用するクエリでとりうる全ての結果を保持します。

This mechanism supports a wide range of queries and is suitable for most applications. However, it does not support some kinds of queries you may be used to from other database technologies.

このメカニズムは幅広いクエリをサポートし、ほとんどのアプリケーションに適合します。しかし、他のデータベーステクノロジで使っていた、いくつかのクエリをサポートしていません。

Entities Without a Filtered Property Are Never Returned by a Query

An index only contains entities that have every property referred to by the index. If an entity does not have a property referred to by an index, the entity will not appear in the index, and will never be a result for the query that uses the index.

インデックスはインデックスによって参照される全てのプロパティを持つエンティティのみ保持します。もしエンティティがインデックスによって参照されるプロパティを持っていない場合、そのエンティティはインデックス内に現れません。そして、インデックスを使用したクエリの結果に決してなりません。

Note that the App Engine datastore makes a distinction between an entity that does not possess a property and an entity that possesses the property with a null value (null). If you want every entity of a kind to be a potential result for a query, you can use a JDO or JPA data class, which always assigns a value to every property that corresponds to a field in the class.

App Engine datastoreはプロパティ自体を保持していないエンティティと、プロパティは存在するがnull値であるプロパティを識別します。もしあなたの欲している、ある種の全てのエンティティをクエリの結果にしたい場合、クラスのフィールドに対応する全てのプロパティを値に常にアサインするJDOとJPAデータクラスを使うことができます。

Properties that Aren't Indexed

Property values that aren't indexed are not findable by queries. This includes properties that are marked as not indexed, as well as properties with values of the long text value type (Text) or the long binary value type (Blob).

インデクシングされないプロパティの値は、クエリによって見つけることができません。これにはインデックスしないとマークされたプロパティと、長いテキストの型(Text)や長い名バイナリの型(Blob)の値をもつプロパティが含まれます。

A query with a filter or sort order on a property will never match an entity whose value for the property is a Text or Blob, or which was written with that property marked as not indexed. Properties with such values behave as if the property is not set with regard to query filters and sort orders.

TextとBlobのプロパティ、もしくはインデックスしないようにマークされたプロパティをクエリのフィルタやソート順に指定した場合、そのエンティティは決してマッチしません。それらのようなプロパティは、プロパティがセットされていないように振る舞います。

Property Values of Mixed Types are Ordered By Type

When two entities have properties of the same name but of different value types, an index of the property sorts the entities first by value type, then by an order appropriate to the type. For example, if two entities each have a property named "age," one with an integer value and one with a string value, the entity with the integer value will always appear before the entity with the string value when sorted by the "Age" property, regardless of the values themselves.

2つのエンティティが同じ名前だが異なる型であるプロパティをもつとき、プロパティのインデックスは最初に値の型でソートし、次に型に適切にソートします。例えば、2つのエンティティが"age"という名前のプロパティを持ち、一つは整数の値をもち、もう一方は文字列の値を持つ場合、”Age"プロパティでソートするとその値を意識せずに整数の値をもつエンティティは常に文字列の値を持つエンティティの前に現れます。

This is especially worth noting in the case of integers and floating point numbers, which are treated as separate types by the datastore. A property with the integer value 38 is sorted before a property with the floating point value 37.5, because all integers are sorted before floats.

これは、Datastore内で別の型として扱われる、整数と浮動小数点の場合に、特に注目すべきことです。整数の値、38を持つプロパティが、浮動小数点の37.5の前にソートされます。なぜなら全ての整数型は浮動小数点の前にソートされるからです。

(If you're using JDO or JPA, this situation does not arise unless you modify a field's type without updating existing entities in the datastore, or use the low-level datastore API or a non-Java API.)

(もしJDOかJPAを使っている場合、このシチュエーションはDatastoreに存在するエンティティのフィールドの型を変更したり、低レベルDatastoreAPいや非JavaAPIを使わない限り発生しません。)

Defining Indexes With Configuration

App Engine builds indexes for several simple queries by default. For other queries, the application must specify the indexes it needs in a configuration file named datastore-indexes.xml. If the application running under App Engine tries to perform a query for which there is no corresponding index (either provided by default or described in datastore-indexes.xml), the query will fail.

App Engineはデフォルトでいくつかのシンプルなクエリ用にインデックスを構築します。他のクエリに対しては、アプリケーションは datastore-indexes.xmlという名前の設定ファイルでインデックスを指定しなければなりません。もしApp Engineで動作しているアプリケーションが、適切なインデックスがない(デフォルトかまたはdatastore-indexes.xmlで提供されない)クエリを実行すると、そのクエリは失敗します。

App Engine provides automatic indexes for the following forms of queries:

App Engineは下記の形のクエリのために自動的にインデックスを提供します。

  • queries using only equality and ancestor filters
  • queries using only inequality filters (which can only be of a single property)
  • queries with only one sort order on a property, either ascending or descending
  • 等号と祖先フィルタのみを使ったクエリ
  • 不等号フィルタ(一つのプロパティに)のみ使ったクエリ
  • (昇順、降順問わず)一つのソート順のみを使ったクエリ

Other forms of queries require their indexes to be specified in datastore-indexes.xml, including:

他の形のクエリはdatastore-indexes.xmlでインデックスを指定する必要があります

  • queries with multiple sort orders
  • queries with a sort order on keys in descending order
  • queries with one or more inequality filters on a property and one or more equality filters over other properties
  • queries with inequality filters and ancestor filters
  • 複数のソート順を指定したクエリ
  • キーに降順のソート順を指定したクエリ
  • 1つ以上の不等号フィルタをプロパティに指定し、一つ以上の等号フィルタを別のプロパティに指定したクエリ
  • 不等号フィルタと祖先フィルタを使用したクエリ

The development web server makes managing index configuration easy: Instead of failing to execute a query that does not have an index and requires it, the development web server can generate configuration for an index that would allow the query to succeed. If your local testing of your application calls every possible query the application will make (every combination of kind, ancestor, filter and sort order), the generated entries will represent a complete set of indexes. If your testing might not exercise every possible query form, you can review and adjust the index configuration before uploading the application.

開発用Webサーバでは、インデックスの設定を簡単に管理します。インデックスのないクエリの実行を失敗させる代わりに、開発用Webサーバはクエリが成功するようなインデックスの設定を生成することができます。もしあなたのアプリケーションをローカルテストで呼び出すとアプリケーションで発生する全ての可能性のあるクエリが作られ(全ての種類の組み合わせ、祖先、フィルタとソート順)、生成されたエントリは完全なインデックスのセットとして表されます。もし、テストが全ての可能性のあるクエリの形をテストしていない場合、アプリケーションをアップロードする前にインデックスを見直して調整することができます。

You can define indexes manually using a configuration file named datastore-indexes.xml in the WEB-INF/ directory of your application's WAR. If you have automatic index configuration enabled (see below), the development server creates an index configuration in a file named datastore-indexes-auto.xml in a directory named WEB-INF/appengine-generated/, and uses both files to determine the full set of indexes.

あなたのアプリケーションのWARディレクトリにあるWEB-INF/にあるdatastore-indexes.xmlという名前の設定ファイルを使ってインデックスを手動で定義することもできます。もし自動的インデックス設定を有効にしていると(下記参照)、開発サーバはインデックス設定をWEB-INF/appengine-generated/というディレクトリの中にある、datastore-indexes-auto.xmlというファイルに作成し、どちらのファイルもインデックスのフルセットを決定するのに使用します。

Consider once again the following example query:

次のクエリについて再度考えて見ましょう。

select from Person where lastName = 'Smith'
                      && height < 72
                   order by height desc

The configuration for the index needed by this query would appear in datastore-indexes.xml as follows:

このクエリのインデックスに必要な設定はdatastore-indexes.xmlにあらわれます。

<?xml version="1.0" encoding="utf-8"?>
<datastore-indexes
  xmlns="http://appengine.google.com/ns/datastore-indexes/1.0"
  autoGenerate="true">
    <datastore-index kind="Person" ancestor="false">
        <property name="lastName" direction="asc" />
        <property name="height" direction="desc" />
    </datastore-index>

</datastore-indexes>

If the <datastore-indexes> element in datastore-indexes.xml has the attribute autoGenerate="true" (as above) or if the app does not have a datastore-indexes.xml file, automatic index configuration is enabled. With automatic index configuration enabled, if the app performs this query in the development server and no configuration for the index exists, the server adds this index configuration to the datastore-indexes-auto.xml file.

もし、datastore-indexes.xmlファイルの要素にautoGenerate="true"属性がある場合、またはdatastore-indexes.xmlファイルが存在しない場合に、自動インデックス設定が有効になります。自動インデックス設定が有効な場合、アプリケーションは、開発サーバ上でかつインデックスの設定が存在しない場合に、このクエリに対して、datastore-indexes-auto.xmlファイルにインデックスの設定を追加します。

For more information on datastore-indexes.xml and datastore-indexes-auto.xml, see Java Datastore Index Configuration.

datastore-indexes.xmlとdatastore-indexes-auto.xmlについての詳細はJava Datastore Index Configurationを参照してください。

Queries on Keys

Entity keys can be the subject of a query filter or sort order. In JDO, you refer to the entity key in the query using the primary key field of the object. The datastore considers the complete key value for such queries, including the entity's parent path, the kind, and the app-assigned key name string or system-assigned numeric ID.

エンティティーのキーはクエリフィルタやソート順の対象とすることができます。JDOでは、オブジェクトのプライマリキーフィールドを使って、クエリのエンティティキーを参照します。Datastoreは、エンティティの親のパス、種類、アプリケーションで設定したキーの名前文字列またはシステムがアサインした数値のIDを含むクエリーを完全なキーと認識します。

Because an entity key is unique across all entities in the system, key queries make it easy to retrieve entities of a given kind in batches, such as for a batch dump of the contents of the datastore. Unlike JDOQL ranges, this works efficiently for any number of entities.

エンティティのキーはシステム内の全てのエンティティで一意であるため、キーによるクエリーはDatastoreのコンテンツのバッチダンプのようなバッチで、与えられた種類のエンティティを抽出することを簡単にします。JDOQLの範囲と異なり、これはどんな数のエンティティでも効率的に働きます。

Keys are ordered first by parent path, then by kind, then by key name or ID. Kinds and key names are strings and are ordered by byte value. IDs are integers and are ordered numerically. If entities of the same parent and kind use a mix of key name strings and numeric IDs, entities with numeric IDs are considered to be less than entities with key name strings. Elements of the parent path are compared similarly: by kind (string), then by key name (string) or ID (number).

キーは最初に親のパスによって順序付けられ、次に種類、次にキーの名前かIDとなります。種類とキーの名前は文字列で、バイト値によって順序付けられます。IDは整数で、数値的に順序付けられます。エンティティが同じ親と種類を持つ場合はキーの名前と数値IDの複合キーを使い、数値のIDをもつエンティティは名前文字列キーをもつエンティティより少ないと考えられます。親のエレメントパスは似たように、種類(String)、次にキー名(String)またはID(数値)の順で比較されます。

Queries involving keys use indexes just like queries involving properties, with one minor difference: Unlike with a property, a query with an equality filter on the key that also has additional filters must use a custom index defined in the app's index configuration file. As with all queries, the development web server creates appropriate configuration entries in this file when a query that needs a custom index is tested.

キーを使ったクエリは、プロパティを使ったクエリと同じくインデックスを使います。1つの小さな違いがあります。プロパティのときと異なり、キーに対する等号フィルタを持ち、追加のフィルタもまたもつクエリは、アプリケーションのインデックス設定ファイルにカスタムインデックス定義をしなければなりません。全てのクエリ同様に、カスタムインデックスが必要なクエリがテストされたときに、開発Webサーバは適切な設定を作成します。

Restrictions on Queries

The nature of the index query mechanism imposes a few restrictions on what a query can do.

このインデックスクエリのメカニズムの特質は、クエリが何ができるかに多少の制限を加えます。

Filtering Or Sorting On a Property Requires That the Property Exists

プロパティのフィルタやソートには、そのプロパティが存在する必要がある

A query filter condition or sort order for a property also implies a condition that the entity have a value for the property.

プロパティへのクエリフィルタの条件やソート順、エンティティの暗黙の条件もまたプロパティの値を持ちます。

A datastore entity is not required to have a value for a property that other entities of the same kind have. A filter on a property can only match an entity with a value for the property. Entities without a value for a property used in a filter or sort order are omitted from the index built for the query.

Datastoreのエンティティは、同種のほかのエンティティがもっているプロパティの値を必要としません。プロパティへのフィルタはプロパティの値を持っているエンティティにのみマッチすることができます。プロパティの値を持っていないエンティティはフィルタやソート順で使われると、そのクエリのインデックス構築から取り除かれます。

No Filter That Matches Entities That Do Not Have a Property

プロパティをもたないエンティティにフィルタはマッチしません。

It is not possible to perform a query for entities that are missing a given property. One alternative is to create a fixed (modeled) property with a default value of null, then create a filter for entities with null as the property value.

与えられたプロパティが存在しないエンティティにクエリを実行することはできません。一つの代替手段としてはデフォルト値がnullの固定されたプロパティをつくり、プロパティの値がnullのエンティティのフィルタを作ることです。

Inequality Filters Are Allowed On One Property Only

不等号フィルタは一つのプロパティにのみ許されます。

A query may only use inequality filters (<, <=, >=, >) on one property across all of its filters.

クエリは一つのプロパティにのみ不等号フィルタ (<, <=, >=, >)を使うことができます。

For example, this query is allowed:

例えばこのクエリは許可されます。

select from Person where birthYear >= minBirthYearParam
                      && birthYear <= maxBirthYearParam

However, this query is not allowed, because it uses inequality filters on two different properties in the same query:

しかしこのクエリは許可されません。なぜなら、同じクエリで不等号フィルタを異なるプロパティに使用しているからです。

select from Person where birthYear >= minBirthYearParam
                      && height >= minHeightParam   // ERROR

Filters can combine equal (==) comparisons for different properties in the same query, including queries with one or more inequality conditions on a property. This is allowed:

同じクエリで、不等号フィルタを使っていても、等号ならば異なるフィルタに使うことができます。これは許可されます。

select from Person where lastName == lastNameParam
                      && city == cityParam
                      && birthYear >= minBirthYearParam

The query mechanism relies on all results for a query to be adjacent to one another in the index table, to avoid having to scan the entire table for results. A single index table cannot represent multiple inequality filters on multiple properties while maintaining that all results are consecutive in the table.

クエリのメカニズムは、テーブル全体をスキャンしてしまうことを避けるために、インデックステーブルでお互い隣接するようにクエリの全ての結果を信頼します。一つのインデックステーブルは、テーブルの全ての結果が連続して並ぶように管理するために、複数のプロパティに対する複数の不等号フィルタを表すことができません。

Properties In Inequality Filters Must Be Sorted Before Other Sort Orders

不等号フィルタのプロパティは、他のソート順の前にソートされなければならない。

If a query has both a filter with an inequality comparison and one or more sort orders, the query must include a sort order for the property used in the inequality, and the sort order must appear before sort orders on other properties.

クエリが不等号フィルタと1つ以上のソート順を持つ場合、そのクエリは不等号フィルタで使ったプロパティのソート順を含めなければならず、そのソート順はほかのプロパティのソート順の前に現れなければなりません。

This query is not valid, because it uses an inequality filter and does not order by the filtered property:

このクエリは不正です。なぜなら不等号フィルタを使っており、そのフィルタプロパティでソートしていないからです。

select from Person where birthYear >= minBirthYearParam
                order by lastName                    // ERROR

Similarly, this query is not valid because it does not order by the filtered property before ordering by other properties:

同様に、このクエリも不正です。なぜなら、フィルタされたプロパティのソートの前に、他のプロパティのソートをしているからです。

select from Person where birthYear > minBirthYearParam
                order by lastName, birthYear         // ERROR

This query is valid:

このクエリは有効です。

select from Person where birthYear >= minBirthYearParam
                order by birthYear, lastName

To get all results that match an inequality filter, a query scans the index table for the first matching row, then returns all consecutive results until it finds a row that doesn't match. For the consecutive rows to represent the complete result set, the rows must be ordered by the inequality filter before other sort orders.

不等号フィルタにマッチした全ての結果を得るために、クエリはインデックステーブルをスキャンし、最初にマッチする行を探します。次に行がマッチしなくなるまで、連続する結果を返します。連続した行が完全な結果セットを表すために、その行は他のソート順で並び替える前に不等号フィルタによってソートしなければなりません。

Sort Orders and Properties With Multiple Values

Due to the way properties with multiple values are indexed, the sort order for these properties is unusual:

複数の値を持つプロパティをインデクシングするため、これらのプロパティのソート順は通常と異なります。

  • If the entities are sorted by a multi-valued property in ascending order, the value used for ordering is the smallest value.
  • If the entities are sorted by a multi-valued property in descending order, the value used for ordering is the greatest value.
  • Other values do not affect the sort order, nor does the number of values.
  • In the case of a tie, the key of the entity is used as the tie-breaker.
  • エンティティが複数の値を持つプロパティの昇順でソートされた場合、その値は小さい値から順序付けられます。
  • エンティティが複数の値を持つプロパティの降順でソートされた場合、その値は大きい値から順序付けられます。
  • 他の値はソート順に影響しません、数値の値もです。
  • 等しい場合は、エンティティのキーがタイブレーカーとして使われます。

This sort order has the unusual consequence that [1, 9] comes before [4, 5, 6, 7] in both ascending and descending order.

このソート順は、通常とはことなる順序をもちます。[1, 9]は昇順でも、降順でも[4,5,6,7]の前に来ます。

One important caveat is queries with both an equality filter and a sort order on a multi-valued property. In those queries, the sort order is disregarded. For single-valued properties, this is a simple optimization. Every result would have the same value for the property, so the results do not need to be sorted further.

重要な警告の一つは、等号フィルタとソート順の両方を、複数の値を持つプロパティに適用したクエリです。これらのクエリはソート順が無視されます。単一値のプロパティのため、最適化されます。各結果はプロパティと同じ値を持つため、その結果はこれ以上ソートする必要がありません。

However, multi-valued properties may have additional values. Since the sort order is disregarded, the query results may be returned in a different order than if the sort order were applied. (Restoring the dropped sort order would be expensive and require extra indices, and this use case is rare, so the query planner leaves it off.)

しかし、複数の値のプロパティは追加の値を持ちます。ソート順が無視されるため、クエリの結果はソート順が適用された場合と異なる順で返されるかもしれません。(落とされたソート順を復元するのは高価になり、追加のインデックスが必要になります。そして、この使い方はめったにないために、クエリプランナはそのままにしています。)

Big Entities and Exploding Indexes

As described above, every property (that doesn't have a Text or Blob value) of every entity is added to at least one index table, including a simple index provided by default, and any indexes described in the application's datastore-indexes.xml file that refer to the property. For an entity that has one value for each property, App Engine stores a property value once in its simple index, and once for each time the property is referred to in a custom index. Each of these index entries must be updated every time the value of the property changes, so the more indexes that refer to the property, the more time it will take to update the property.

上記のとおり、各エンティティの各プロパティ(TextとBlob値を除く)は、少なくとも一つのインデックステーブルに追加されます。インデックステーブルには、デフォルトで提供される単純なインデックス、そしてプロパティを参照するための、アプリケーションのdatastore-indexes.xmlファイルに記載されたインデックスがあります。全てのプロパティが単一の値をもつエンティティのため、AppEngineはプロパティの値を、シンプルインデックスにいったん格納します。そして、そのプロパティが参照されるカスタムインデックスに格納します。それらのインデックスのエンティティはプロパティの値が変更されるたび更新されなければなりません。よってインデックスが参照するプロパティが多くなると、プロパティの更新により時間がかかるようになります。

To prevent the update of an entity from taking too long, the datastore limits the number of index entries that a single entity can have. The limit is large, and most applications will not notice. However, there are some circumstances where you might encounter the limit. For example, an entity with very many single-value properties can exceed the index entry limit.

エンティティの更新が長くなりすぎないように、Datastoreは単一のエンティティが持つことのできる、インデックスのエンティティの数を制限します。その制限は大きく、ほとんどのアプリケーションは気付くことはないでしょう。しかし、いくつかの場合には制限に達することもあります。例えば、エンティティがとてもたくさんの単一値のプロパティをもっている場合、インデックスのエントリの制限を越えるかもしれません。

Properties with multiple values store each value as a separate entry in an index. An entity with a single property with very many values can exceed the index entry limit.

複数の値をとるプロパティはそれぞれの値が別のエントリとしてインデックスに保存されます。とても数多くの値をもつ1つのプロパティをもつエンティティはインデックスエントリの制限を超過する可能性があります。

Custom indexes that refer to multiple properties with multiple values can get very large with only a few values. To completely record such properties, the index table must include a row for every permutation of the values of every property for the index.

複数の値を持つ複数のプロパティを参照するカスタムインデックスは、少ない値でとても大きくなります。そのようなプロパティを完全に記録するため、インデックステーブルは、各プロパティの値の各順列の行を保持しなければなりません。

For example, the following index (described in datastore-indexes.xml syntax) includes the x and y properties for entities of the kind MyModel:

例えば、次のインデックス(datastore-indexes.xmlの文法で記載しています)は、MuModel種のエンティティでxとyのプロパティをもっています。

<?xml version="1.0" encoding="utf-8"?>
<datastore-indexes>
    <datastore-index kind="MyModel">
        <property name="x" direction="asc" />
        <property name="y" direction="asc" />
    </datastore-index>

</datastore-indexes>

The following code creates an entity with 2 values for the property x and 2 values for the property y:

次のコードはプロパティxに2つの値、プロパティyにも2つの値を持つエンティティを作成します。 

        MyModel m = new MyModel();

        m.setX(Arrays.asList("one", "two"));
        m.setY(Arrays.asList("three", "four"));

        pm.makePersistent(m);

To accurately represent these values, the index must store 12 property values: 2 each for the built-in indexes on x and y, and 2 for each of the 4 permutations of x and y in the custom index. With many values of multi-valued properties, this can mean an index must store very many index entries for a single entity. You could call an index that refers to multiple properties with multiple values an "exploding index," because it can get very large with just a few values.

これらの値を正確に表現するため、インデックスは12のプロパティの値を格納しなければなりません。xとyの組み込みインデックスのために2つ、カスタムインデックスにxとyの各順列4つを2つです。複数の値をもつプロパティがたくさんの値を持つとき、単一のエンティティのためにとてもたくさんのプロパティをインデックスに保持しなければならないことを意味します。複数の値を持つ複数のプロパティを参照するインデックスを「爆発したインデックス」と呼びます。なぜなら、少しの値のために非常に大きくなるためです。

If a put() would result in a number of index entries that exceeds the limit, the call will fail with an exception. If you create a new index that would contain a number of index entries that exceeds the limit for any entity when built, queries against the index will fail, and the index will appear in the "Error" state in the Admin Console.

put()の結果、インデックスのエントリの制限を超えた場合、その呼び出しは失敗し例外になります。エンティティを作成するときに、インデックスエントリの制限を越えた新しいインデックスを作ると、そのインデックスに対するクエリは失敗し、そのインデックスはAdminConsoleに「エラー」状態として表示されます。

You can avoid exploding indexes by avoiding queries that would require a custom index using a list property. As described above, this includes queries with multiple sort orders, a mix of equality and inequality filters, and ancestor filters.

リストプロパティを使う、カスタムインデックスを必要とするクエリを避けることによって、インデックスの爆発を防ぐことができます。上記の通り、これには複数のソート順、等号と不等号を混在したフィルタ、祖先フィルタを含みます。

0 件のコメント: