ここでは、カスタム述語エバリュエーターを実装して、Query Builder を拡張する方法について説明します。
Query Builder を使用すると、コンテンツリポジトリへのクエリを簡単に実行できます。CQ には、データの処理に役立つ一連の述語エバリュエーターが付属しています。
しかし、カスタム述語エバリュエーターを実装することによって、複雑さを軽減し、セマンティックを向上させて、クエリを単純化することができます。
他にも、カスタム述語では、以下のような XPath では直接実行できないことも実行できます。
- 何らかのサービスの何らかのデータの検索
- 計算に基づくカスタムフィルタリング
注意:
カスタム述語を実装する際は、パフォーマンスの問題を考慮する必要があります。
注意:
クエリの例については、Query Builder の節を参照してください。
GitHub のコード
このページのコードは GitHub にあります
- GitHub の aem-search-custom-predicate-evaluator プロジェクトを開きます
- プロジェクトを ZIP ファイルとしてダウンロードします
述語エバリュエーターは、クエリの制約を定義する特定の述語を評価します。
特定の JCR クエリに対する高度な検索制約("width > 200" など)を、実際のコンテンツモデルに合わせてマッピングします(例:metadata/@width > 200)。ノードを手動でフィルタリングして、制約をチェックすることもできます。
注意:
PredicateEvaluator および com.day.cq.search パッケージについて詳しくは、Java のドキュメントを参照してください。
一例として、この節では、次のレプリケーションメタデータに基づくデータに役立つカスタム述語エバリュエーターを作成する方法について説明します。
- cq:lastReplicated:最終レプリケーションアクションの日付を格納
- cq:lastReplicatedBy:最終レプリケーションアクションを呼び出したユーザーの ID を格納
- cq:lastReplicationAction:最終レプリケーションアクション(アクティベート、アクティベート解除など)を格納
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 つのレプリケーションプロパティ間の関係が一目ではわかりません。カスタム述語エバリュエーターを実装すると、複雑さが軽減され、このクエリのわかりやすさが向上します。
path=/content replic.by=admin replic.since=2013-01-01T00:00:00.000+01:00 replic.action=Activate
注意:
Maven を使用した新しい AEM プロジェクトの設定については、Apache Maven を使用した AEM プロジェクトの構築方法で説明されています。
まず、プロジェクトの Maven 依存関係を更新する必要があります。PredicateEvaluator は cq-search アーティファクトの一部なので、Maven の pom ファイルに追加する必要があります。
注意:
cq-search は OSGi コンテナによって提供されるので、cq-search の依存関係の範囲は provided に設定されます。
pom.xml
次のスニペットは、ユニファイド diff 形式での違いを示しています。
@@ -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>
|
cq-search プロジェクトには、AbstractPredicateEvaluator 抽象クラスが含まれます。このクラスをいくつかのステップで拡張して、独自のカスタム述語エバリュエーター(PredicateEvaluator)を実装できます。
注意:
次の手順では、データをフィルタリングする Xpath 式を作成する方法について説明します。もう 1 つの方法は、データを行単位で選択する includes メソッドを実装することです。詳しくは、Java のドキュメントを参照してください。
-
src/main/java/com/adobe/aem/docs/search/ReplicationPredicateEvaluator.java
次のスニペットは、ユニファイド diff 形式での違いを示しています。
@@ -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 の名前は述語名で、クエリを組み立てる際に使用されます。
src/main/java/com/adobe/aem/docs/search/ReplicationPredicateEvaluator.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
/* * #%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 * * http://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