Query Builder 用のカスタム述語エバリュエーターの実装

最終更新日: 2023-09-22
  • トピック:
  • Developing
    このトピックの詳細を表示
  • 作成対象:
  • Developer

この節では、 Query Builder カスタム述語エバリュエーターを実装する。

概要

The Query Builder は、コンテンツリポジトリに対して簡単にクエリを実行する方法を提供します。 CQ には、データの処理に役立つ一連の述語エバリュエーターが付属しています。

ただし、複雑さを軽減し、より適切なセマンティクスを確保するカスタム述語エバリュエーターを実装することで、クエリを簡略化できます。

また、カスタム述語は、XPath で直接実行できない他の操作も実行できます。例えば、次の操作を行います。

  • 一部のサービスからのデータの検索
  • 計算に基づくカスタムフィルタリング
メモ

カスタム述語を実装する際は、パフォーマンスの問題を考慮する必要があります。

メモ

クエリの例については、Query Builder の節を参照してください。

GitHub のコード

このページのコードは GitHub にあります。

述語エバリュエーターの詳細

述語エバリュエーターは、クエリの制約を定義する特定の述語を評価します。

これは、実際のコンテンツモデル ( 例えば、metadata/@width > 200) に適合する特定の JCR クエリに、上位レベルの検索制約(「幅 > 200」など)をマッピングします。 ノードを手動でフィルタリングして、制約をチェックすることもできます。

メモ

詳しくは、 PredicateEvaluator そして com.day.cq.search パッケージ ( Java™ドキュメント.

レプリケーションメタデータ用のカスタム述語エバリュエーターの実装

一例として、この節では、次のレプリケーションメタデータに基づくデータに役立つカスタム述語エバリュエーターを作成する方法について説明します。

  • cq:lastReplicated:最終レプリケーションアクションの日付を格納

  • cq:lastReplicatedBy:最終レプリケーションアクションを呼び出したユーザーの ID を格納

  • cq:lastReplicationAction:最終レプリケーションアクション(アクティベート、アクティベート解除など)を格納

デフォルトの述語エバリュエーターを使用したレプリケーションメタデータのクエリ

次のクエリでは、年初から admin によってアクティベートされた /content ブランチ内のノードのリストを取得します。

path=/content

1_property=cq:lastReplicatedBy
1_property.value=admin

2_property=cq:lastReplicationAction
2_property.value=Activate

daterange.property=cq:lastReplicated
daterange.lowerBound=2013-01-01T00:00:00.000+01:00
daterange.lowerOperation=>=

このクエリは有効ですが、解読しにくく、3 つのレプリケーションプロパティ間の関係が一目ではわかりません。カスタム述語エバリュエーターを実装すると、複雑さが軽減され、このクエリのセマンティックが向上します。

目的

ReplicationPredicateEvaluator の目的は、以下のような構文を使用して上記のクエリをサポートすることです。

path=/content

replic.by=admin
replic.since=2013-01-01T00:00:00.000+01:00
replic.action=Activate

カスタム述語エバリュエーターを使用して、レプリケーションメタデータの述語をグループ化すると、意味のあるクエリを作成できます。

Maven 依存関係の更新

メモ

Maven を使用した新しいAdobe Experience Manager(AEM) プロジェクトの設定については、次のドキュメントを参照してください。 Apache Maven を使用してAEMプロジェクトを構築する方法.

まず、プロジェクトの Maven の依存関係を更新します。 The PredicateEvaluator は、 cq-search アーティファクトの場合は、Maven の pom.xml ファイルに追加する必要があります。

メモ

の範囲 cq-search 依存関係は次のように設定されます。 provided 理由: cq-searchOSGi コンテナ。

pom.xml

次のスニペットに、 統合差分形式

@@ -120,6 +120,12 @@
             <scope>provided</scope>
         <dependency>
+            <groupid>com.day.cq</groupid>
+            <artifactid>cq-search</artifactid>
+            <version>5.6.4</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupid>junit</groupid>
             <artifactid>junit</artifactid>
             <version>3.8.1</version></dependency>

aem-search-custom-predicate-evaluator- pom.xml

ReplicationPredicateEvaluator の作成

cq-search プロジェクトには、AbstractPredicateEvaluator 抽象クラスが含まれます。このクラスを数ステップで拡張して、独自のカスタム述語エバリュエーター (PredicateEvaluator)を実装できます。

メモ

次の手順では、データをフィルタリングする Xpath 式を作成する方法について説明します。この他に、データを行単位で選択する includes メソッドを実装する方法もあります。詳しくは、 Java™ドキュメント を参照してください。

  1. を拡張する Java™クラスの作成 com.day.cq.search.eval.AbstractPredicateEvaluator

  2. 次のように、@Component を使用してクラスに注釈を付けます

    src/main/java/com/adobe/aem/docs/search/ReplicationPredicateEvaluator.java

    次のスニペットに、 統合差分形式

@@ -19,8 +19,11 @@
  */
 package com.adobe.aem.docs.search;

+import org.apache.felix.scr.annotations.Component;
+
 import com.day.cq.search.eval.AbstractPredicateEvaluator;

+@Component(metatype = false, factory = "com.day.cq.search.eval.PredicateEvaluator/repli")
 public class ReplicationPredicateEvaluator extends AbstractPredicateEvaluator {

 }

aem-search-custom-predicate-evaluator- src/main/java/com/adobe/aem/docs/search/ReplicationPredicateEvaluator.java

メモ

factory は、com.day.cq.search.eval.PredicateEvaluator/ で始まりカスタム PredicateEvaluator の名前で終わる一意の文字列にする必要があります。

メモ

PredicateEvaluator の名前は述語名で、クエリを組み立てる際に使用されます。

  1. オーバーライド:

    public String getXPathExpression(Predicate predicate, EvaluationContext context)
    

    override メソッドで、 Xpath 次に基づく式 Predicate 引数で与えられた。

レプリケーションメタデータ用のカスタム述語エバリュエーターの例

この PredicateEvaluator の完全な実装は、次のクラスのようになります。

src/main/java/com/adobe/aem/docs/search/ReplicationPredicateEvaluator.java

/*
 * #%L
 * aem-docs-custom-predicate-evaluator
 * %%
 * Copyright (C) 2013 Adobe Research
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

package com.adobe.aem.docs.search;

import org.apache.felix.scr.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.day.cq.search.Predicate;
import com.day.cq.search.eval.AbstractPredicateEvaluator;
import com.day.cq.search.eval.EvaluationContext;

@Component(metatype = false, factory = "com.day.cq.search.eval.PredicateEvaluator/repli")

public class ReplicationPredicateEvaluator extends AbstractPredicateEvaluator {

    static final String PE_NAME = "replic";


    static final String PN_LAST_REPLICATED_BY = "cq:lastReplicatedBy";
    static final String PN_LAST_REPLICATED = "cq:lastReplicated";
    static final String PN_LAST_REPLICATED_ACTION = "cq:lastReplicationAction";

    static final String PREDICATE_BY = "by";
    static final String PREDICATE_SINCE = "since";
    static final String PREDICATE_SINCE_OP = " >= ";
    static final String PREDICATE_ACTION = "action";

    Logger log = LoggerFactory.getLogger(getClass());

    /**
     * Returns a XPath expression filtering by replication metadata.
     *
     * @see com.day.cq.search.eval.AbstractPredicateEvaluator#getXPathExpression(com.day.cq.search.Predicate,
     *      com.day.cq.search.eval.EvaluationContext)
     */

    @Override

    public String getXPathExpression(Predicate predicate,
            EvaluationContext context) {

        log.debug("predicate {}", predicate);

        String date = predicate.get(PREDICATE_SINCE);
        String user = predicate.get(PREDICATE_BY);
        String action = predicate.get(PREDICATE_ACTION);

        StringBuilder sb = new StringBuilder();

        if (date != null) {

            sb.append(PN_LAST_REPLICATED).append(PREDICATE_SINCE_OP);
            sb.append("xs:dateTime('").append(date).append("')");

        }

        if (user != null) {

            addAndOperator(sb);
            sb.append(PN_LAST_REPLICATED_BY);
            sb.append("='").append(user).append("'");

        }

        if (action != null) {

            addAndOperator(sb);
            sb.append(PN_LAST_REPLICATED_ACTION);
            sb.append("='").append(action).append("'");

        }

        String xpath = sb.toString();

        log.debug("xpath **{}**", xpath);

        return xpath;

    }

    /**
     * Add an and operator if the builder is not empty.
     *
     * @param sb a {@link StringBuilder} containing the query under construction
     */

    private void addAndOperator(StringBuilder sb) {

        if (sb.length() != 0) {

            sb.append(" and ");

        }

    }

}

aem-search-custom-predicate-evaluator- src/main/java/com/adobe/aem/docs/search/ReplicationPredicateEvaluator.java

このページ