11.3. 検索


Ickle クエリー言語を使用して、ライブラリーおよびリモートクライアント/サーバーモードの両方でリレーショナルおよびフルテキストクエリーを作成します。

API を使用するには、まず QueryFactory をキャッシュに取得してから、.create() メソッドを呼び出し、クエリーで使用する文字列を渡します。各 QueryFactory インスタンスは Search と同じ Cache インスタンスにバインドされますが、それ以外の場合は、複数のクエリーを並行して作成するために使用できるステートレスおよびスレッドセーフオブジェクトになります。

以下に例を示します。

// Remote Query, using protobuf
QueryFactory qf = org.infinispan.client.hotrod.Search.getQueryFactory(remoteCache);
Query q = qf.create("from sample_bank_account.Transaction where amount > 20");

// Embedded Query using Java Objects
QueryFactory qf = org.infinispan.query.Search.getQueryFactory(cache);
Query q = qf.create("from com.acme.Book where price > 20");

// Execute the query
QueryResult<Book> queryResult = q.execute();
注記

クエリーは常に単一のエンティティータイプをターゲットにし、単一のキャッシュの内容に対して評価されます。複数のキャッシュでクエリーを実行したり、複数のエンティティータイプ (結合) を対象とするクエリーを作成したりすることは、サポートされていません。

クエリーの実行と結果のフェッチは、Queryオブジェクトの run() メソッドを呼び出すのと同じくらい簡単です。実行後に、同じインスタンスで run() を呼び出すと、クエリーを再実行します。

11.3.1. ページネーション

Query.maxResults(int maxResults) を使用して、返される結果の数を制限することができます。これを Query.startOffset(long startOffset) と組み合わせて使用すると、結果セットのページネーションを実現できます。

// sorted by year and match all books that have "clustering" in their title
// and return the third page of 10 results
Query<Book> query = queryFactory.create("FROM com.acme.Book WHERE title like '%clustering%' ORDER BY year").startOffset(20).maxResults(10)

11.3.2. ヒット数

QueryResult オブジェクトには、ページネーションパラメーターに関係なく、クエリーの結果の合計数を返すための .hitCount() メソッドがあります。ヒット数は、パフォーマンス上の理由から、インデックス付きクエリーでのみ使用できます。

11.3.3. 反復

Query オブジェクトには、結果を遅延して取得するための .iterator() メソッドがあります。使用後に閉じる必要がある CloseableIterator のインスタンスを返します。

注記

リモートクエリーの反復サポートは現在制限されています。反復する前に、最初にすべてのエントリーをクライアントにフェッチするためです。

11.3.4. 名前付きクエリーパラメーターの使用

実行ごとに新しい Query オブジェクトを作成する代わりに、実行前に実際の値に置き換えることができる名前付きパラメーターをクエリーに含めることができます。これにより、クエリーを 1 度定義し、複数回効率的に実行できます。パラメーターは、Operator の右側でのみ使用でき、通常の定数値ではなく、org.infinispan.query.dsl.Expression.param(String paramName) メソッドによって生成されたオブジェクトを Operator に提供することで、クエリーの作成時に定義されます。パラメーターが定義されたら、以下の例に示すように Query.setParameter(parameterName, value) または Query.setParameters(parameterMap) のいずれかを呼び出すことで設定できます。

QueryFactory queryFactory = Search.getQueryFactory(cache);
// Defining a query to search for various authors and publication years
Query<Book> query = queryFactory.create("SELECT title FROM com.acme.Book WHERE author = :authorName AND publicationYear = :publicationYear").build();

// Set actual parameter values
query.setParameter("authorName", "Doe");
query.setParameter("publicationYear", 2010);

// Execute the query
List<Book> found = query.list();

または、実際のパラメーター値のマップを指定して、複数のパラメーターを一度に設定することもできます。

複数の名前付きパラメーターを一度に設定する

Map<String, Object> parameterMap = new HashMap<>();
parameterMap.put("authorName", "Doe");
parameterMap.put("publicationYear", 2010);

query.setParameters(parameterMap);

注記

クエリーの解析、検証、および実行計画の作業の大部分は、パラメーターでのクエリーの最初の実行時に実行されます。この作業は後続の実行時には繰り返し行われないため、クエリーパラメーターではなく定数値を使用した同様のクエリーの場合よりもパフォーマンスが向上します。

11.3.5. Ickle クエリー言語パーサー構文

Ickle クエリー言語は、フルテキスト用のいくつかのエクステンションを持つ JPQL クエリー言語の小さなサブセットです。

パーサー構文には、以下のような重要なルールがあります。

  • 空白は重要ではありません。
  • フィールド名ではワイルドカードはサポートされません。
  • デフォルトのフィールドがないため、フィールド名またはパスは必ず指定する必要があります。
  • && および || は、フルテキストと JPA 述語の両方で、AND または OR の代わりに使用できます。
  • !NOT の代わりに使用できます。
  • 足りないブール値 Operator は OR として解釈されます。
  • 文字列の用語は、一重引用符または二重引用符で囲む必要があります。
  • ファジー性とブースティングは任意の順序で受け入れられず、常にファジー性が最初になります。
  • <> の代わりに != が許可されます。
  • ブーディングは、>>=< Operator には適用できません。同じ結果を達成するために範囲を使用することができます。

11.3.5.1. Operator のフィルタリング

Ickle はインデックス化されたフィールドとインデックス化されていないフィールドの両方に使用できる多くの Operator のフィルタリングをサポートします。

Operator説明

in

左のオペランドが引数として指定された値のコレクションからの要素のいずれかと等しいことを確認します。

FROM Book WHERE isbn IN ('ZZ', 'X1234')

like

(文字列として想定される) 左側の引数が、JPA ルールに準拠するワイルドカードパターンと一致することを確認します。

FROM Book WHERE title LIKE '%Java%'

=

左側の引数が指定の値と完全に一致することを確認します。

FROM Book WHERE name = 'Programming Java'

!=

左側の引数が指定の値とは異なることを確認します。

FROM Book WHERE language != 'English'

>

左側の引数が指定の値よりも大きいことを確認します。

FROM Book WHERE price > 20

>=

左側の引数が指定の値以上であることを確認します。

FROM Book WHERE price >= 20

<

左側の引数が指定の値未満であることを確認します。

FROM Book WHERE year < 2012

左側の引数が指定の値以下であることを確認します。

FROM Book WHERE price ⇐ 50

between

左側の引数が指定された範囲の制限の間にあることを確認します。

FROM Book WHERE price BETWEEN 50 AND 100

11.3.5.2. ブール値の条件

以下の例では、複数の属性条件を論理結合 (and) および非結合 (or) 演算子と組み合わせて、より複雑な条件を作成する方法を示しています。ブール値演算子のよく知られる演算子の優先順位ルールがここで適用されるため、Operator の順序は関連性がありません。ここで、or が最初に呼び出された場合でも、and Operator の優先順位は or よりも高くなります。

# match all books that have "Data Grid" in their title
# or have an author named "Manik" and their description contains "clustering"

FROM com.acme.Book WHERE title LIKE '%Data Grid%' OR author.name = 'Manik' AND description like '%clustering%'

ブール値の否定は論理演算子の中で優先され、次の単純な属性条件にのみ適用されます。

# match all books that do not have "Data Grid" in their title and are authored by "Manik"
FROM com.acme.Book WHERE title != 'Data Grid' AND author.name = 'Manik'

11.3.5.3. ネストされた条件

論理演算子の優先順位の変更は、括弧を使用して行います。

# match all books that have an author named "Manik" and their title contains
# "Data Grid" or their description contains "clustering"
FROM com.acme.Book WHERE author.name = 'Manik' AND ( title like '%Data Grid%' OR description like '% clustering%')

11.3.5.4. 属性の選択

一部のユースケースでは、属性のごく一部のみがアプリケーションによって実際に使用されている場合、特にドメインエンティティーにエンティティーが埋め込まれている場合、ドメインオブジェクト全体を返すのはやり過ぎです。クエリー言語を使用すると、プロジェクションを返す属性 (または属性パス) のサブセットを指定できます。デプロイメントが使用される場合、QueryResult.list() はドメインエンティティー全体を返しませんが、Object[]List (プロジェクト化された属性に対応する配列) を返します。

# match all books that have "Data Grid" in their title or description
# and return only their title and publication year
SELECT title, publicationYear FROM com.acme.Book WHERE title like '%Data Grid%' OR description like '%Data Grid%'

11.3.5.5. ソート

1 つ以上の属性または属性パスに基づいて結果の順序は ORDER BY 句で行われます。複数の並べ替え基準が指定されている場合は、順序によって優先順位が決まります。

# match all books that have "Data Grid" in their title or description
# and return them sorted by the publication year and title
FROM com.acme.Book WHERE title like '%Data Grid%' ORDER BY publicationYear DESC, title ASC

11.3.5.6. グループ化およびアグリゲーション

Data Grid には、グループ化フィールドのセットに従ってクエリー結果をグループ化し、各グループに分類される値のセットに集計関数を適用することにより、各グループからの結果の集計を構築する機能があります。グループ化と集計は、プロジェクションクエリー (SELECT 句に 1 つ以上のフィールドがあるクエリー) にのみ適用できます。

サポートされる集約は avg、sum、count、max および min です。

グループ化フィールドセットは GROUP BY 句で指定し、グループ化フィールドの定義に使用される順番は関係ありません。プロジェクションで選択されたすべてのフィールドは、グループ化フィールドであるか、以下で説明するグループ化関数の 1 つを使用して集約される必要があります。Projection フィールドは集約され、同時にグループ化に使用できます。グループ化フィールドのみを選択し、集計フィールドは選択しないクエリーは有効です。例:ブックマークは作成者別にグループ化し、それらをカウントします。

SELECT author, COUNT(title) FROM com.acme.Book WHERE title LIKE '%engine%' GROUP BY author
注記

選択したすべてのフィールドに集計関数が適用され、グループ化にフィールドが使用されないプロジェクションクエリーが許可されます。この場合、集計は、単一のグローバルグループが存在するかのようにグローバルに計算されます。

11.3.5.7. 集約

以下の集約関数をフィールドに適用できます。

  • avg() - 一連の数字の平均を計算します。許可される値は、java.lang.Number のプリミティブ番号およびインスタンスです。結果は java.lang.Double で表されます。null 以外の値がない場合、結果は代わりに null になります。
  • avg() - null 以外の行の数をカウントし、java.lang.Long を返します。null 以外の値がない場合、結果は代わりに 0 になります。
  • max() - 見つかった最も大きな値を返します。許可される値は java.lang.Comparable のインスタンスである必要があります。null 以外の値がない場合、結果は代わりに null になります。
  • min() - 見つかった最小値を返します。許可される値は java.lang.Comparable のインスタンスである必要があります。null 以外の値がない場合、結果は代わりに null になります。
  • sum() - 数字のセットの合計を計算します。null 以外の値がない場合、結果は代わりに null になります。以下の表は、指定のフィールドに基づいて返されるタイプを示しています。
表11.1 テーブル合計戻り値のタイプ
フィールドタイプ戻り値のタイプ

Integral (BigInteger 以外)

ロング

Float または Double

Double

BigInteger

BigInteger

BigDecimal

BigDecimal

11.3.5.8. グループ化および集計を使用したクエリーの評価

集計クエリーには、通常のクエリーのようにフィルター条件を含めることができます。フィルタリングは、グループ化操作の前後の 2 つのステージで実行できます。グループ化操作の実行前に groupBy() メソッドを起動する前に定義されたフィルター条件はすべて、キャッシュエントリーに直接 (最終的なデプロイメントではなく) キャッシュエントリーに適用されます。これらのフィルター条件は、照会されたエンティティータイプの任意のフィールドを参照でき、グループ化ステージの入力となるデータセットを制限することを目的としています。groupBy() メソッドの呼び出し後に定義されたフィルター条件はすべて、デプロイメントおよびグループ化操作の結果がデプロイメントされます。このフィルター条件は、groupBy() フィールドまたは集約されたフィールドのいずれかを参照できます。select 句で指定されていない集約フィールドを参照することは許可されています。ただし、非集計フィールドと非グループ化フィールドを参照することは禁止されています。このフェーズでフィルタリングすると、プロパティーに基づいてグループの数が減ります。通常のクエリーと同様に、並べ替えも指定できます。順序付け操作は、グループ化操作後に実行され、groupBy() フィールドまたは集約されたフィールドのいずれかを参照できます。

Red Hat logoGithubRedditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

Red Hat ドキュメントについて

Red Hat をお使いのお客様が、信頼できるコンテンツが含まれている製品やサービスを活用することで、イノベーションを行い、目標を達成できるようにします。

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。このような変更は、段階的に実施される予定です。詳細情報: Red Hat ブログ.

会社概要

Red Hat は、企業がコアとなるデータセンターからネットワークエッジに至るまで、各種プラットフォームや環境全体で作業を簡素化できるように、強化されたソリューションを提供しています。

© 2024 Red Hat, Inc.