Datastoreのクエリでがんばるハナシという記事を書きましたが、そこで書いた各種テクニックをサポートするライブラリを作ったので紹介します。現時点でまだβ版(v0.1.0)です。APIを併用するテクニックがあります。APIはとても便利ですがいくつかの制限があり、何よりインデックスサイズに上限がある為スケーラビリティに難があります。APIに出来るだけ頼らないことが本ライブラリの第一の目的です。DatastoreはLIKEやIN/OR条件のフィルタをサポートしません。1これは内部のインデックス構造上の理由によるものですが、本ライブラリを利用することで部分的にですが実現することができます。Filter(>,>=,<,<=)を併用する場合、index.yaml(GAE/Javaの場合はdatastore-indexes.xml)にカスタムインデックスを定義する必要があります。カスタムインデックスは必要なプロパティの組み合わせの数だけ定義しておく必要があります。ある複数フィールドを持つ検索画面UIなどで「未入力・未選択の場合は検索条件に含めない」という仕様があったりすると、その条件を含めないパターンのインデックスも定義しなくてはならなくなり、すぐにインデックス定義数が膨らんでしまいます。カスタムインデックス定義の数やエンティティあたりのインデックスサイズには上限がある為、できる限りカスタムインデックス定義は少なくしておきたいところです。本ライブラリは単一のListプロパティに必要なインデックスを集約しますので、カスタムインデックスの定義を削減して節約することが出来ます。アーキテクチャ本記事では割愛します。用いて記述しています。Library(cloud.google.com/go/datastore)でも同様に動作するはずです。差異があると正しく検索されない為、グローバル変数に保持しておくとよいです。検索項目ごとにラベルを用意します。定数は必須ではないですがラベルはできるだけ短くしておいた方が良い為、可読性を考えて定数化しておくことを推奨します。1文字の場合はunigram、2文字以上の場合はbigramで検索します。title)長文だとインデックス数がかなり大きくなるのでご注意ください。前方一致プレフィックスで検索します。title)biunigram以上にインデックスを消費する為長文には向きません。Datastoreのクエリでがんばるハナシで挙げたテクニックのサンプルを記します。Filterに変換できます。Filterに変換可能です。Filterで実装可能です。}検索OR検索はbit論理和で指定できます。Filterで検索できます。Filterは従来通りに使用可能です。Filter対象のプロパティと、本ライブラリインデックス保存用プロパティ(上記サンプルだとIndexes)とを組み合わせたカスタムインデックスが必要になります。SaveNoFiltersIndexConfigでSaveNoFiltersIndexをtrueに設定しておくと、インデックス保存時に必ず拡張フィルタなし検索用のインデックスが保存されます。Filterが自動で適用されます。この設定がfalseで、拡張フィルタのあり・なしの両パターンの検索がある場合、カスタムインデックスを両パターン分用意しておく必要がありますが、trueにしておくことでカスタムインデックスを半分に節約することができます。トレードオフマージジョイン上述下通り本ライブラリは単一Listプロパティにインデックスを詰め込むことでカスタムインデックス定義を節約することを目的の一つとしていますが、内部的にはマージジョインという仕組みで検索が行われる為、データ件数や条件によってはカスタムインデックスを定義した場合に比べてパフォーマンスが極端に落ちることがあります。2対策カスタムインデックスの併用フィルタ使用頻度の高いプロパティ(例えばユーザーIDなど)は本ライブラリ対象から外して通常プロパティとしてカスタムインデックスを組むことでマージジョインのパフォーマンス劣化を軽減することができます。IndexesCompositeIdxLabels本ライブラリ自体にも複合インデックス機能を持っています。使われるフィルタラベルの組み合わせを設定しておくと内部に複合インデックスが構築され、そのラベルに対するフィルタを複数適用するとマージジョイン劣化が軽減されます。here})複合インデックス機能は指数関数的にインデックスが増えていくので用法用量にご注意ください。複数インデックスを持つラベル(biunigramなど)が含まれるとさらにインデックス数は爆発します。インデックス爆発を防ぐ為に、現在下記の制限があります。CompositeIdxLabelsに指定できるラベル数は最大8Build後の合計拡張インデックス数は最大512超過するとエラーになります。マイグレーション本ライブラリで作成したインデックスに影響のある修正や変更があった場合は保存済み既存エンティティに対して全てマイグレーション(インデックス再保存)を行う必要が生じます。3PUT時レイテンシ本ライブラリを使用すると、(使用方法にもよりますが)基本的にインデックス量は増大します。modeになった場合、レイテンシに大きく影響を与える可能性があります。Spannerなど超強力な新勢力におされて影が薄くなりがちなDatastoreですが、まだまだコスト的にはメリットもあります。今後DatastoreのバックエンドがFirestore(Spanner)に移行されていきますので、そちらの美味しいところを貰ってさらに強力なサービスになっていくことが期待されます。45自分はこれからも安くて美味しいDatastore、使い倒していく所存です!!q(^o^)pあと・・・テスト手伝ってくれた石田さん、Thanks!!JavaやPythonはSDKライブラリレベルでサポートしていますが、カーソルが使えないなどの制限があります。経験的に数百万エンティティくらいではパフォーマンス劣化は落ちませんでした(検索条件にもよりますが)。↩Datastore標準機能でもシングルプロパティインデックスの追加変更はマイグレーションが必要です。カスタムインデックスの追加変更は自動で更新されます。トランザクション周りの制限が緩和されます。upLoginユーザーは見つかりませんでした。