Questo documento descrive come estendere Query Builder implementando un valutatore di predicati personalizzato.
Il Query Builder offre un modo semplice per eseguire query sull’archivio dei contenuti. AEM viene fornito con un insieme di valutatori predicato che consentono di eseguire query sui dati.
Tuttavia, potrebbe essere utile semplificare le query implementando un valutatore di predicati personalizzato che nasconda una certa complessità e garantisca una semantica migliore.
Un predicato personalizzato potrebbe inoltre eseguire altre operazioni non direttamente possibili con XPath, ad esempio:
Quando si implementa un predicato personalizzato, è necessario considerare i problemi di prestazioni.
Puoi trovare esempi di query in Query Builder documento.
Puoi trovare il codice di questa pagina su GitHub
Questo codice collegato su GitHub e i frammenti di codice in questo documento vengono forniti solo a scopo dimostrativo.
Un valutatore di predicati gestisce la valutazione di alcuni predicati, che sono i vincoli di definizione di una query.
Mappa un vincolo di ricerca di livello superiore (ad esempio width>200
) a una query JCR specifica adatta al modello di contenuto effettivo (ad esempio, metadata/@width > 200
). Oppure può filtrare manualmente i nodi e controllarne i vincoli.
Per ulteriori informazioni su PredicateEvaluator
e com.day.cq.search
pacchetto vedere Documentazione Java.
Ad esempio, questa sezione descrive come creare un valutatore di predicati personalizzato che aiuti i dati basati sui metadati di replica:
cq:lastReplicated
che memorizza la data dell’ultima azione di replicacq:lastReplicatedBy
che memorizza l’id dell’utente che ha attivato l’ultima azione di replicacq:lastReplicationAction
che memorizza l’ultima azione di replica (ad esempio Attivazione, Disattivazione)La query seguente recupera l’elenco dei nodi in /content
ramo attivato da admin
dall'inizio dell'anno.
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=>=
Questa query è valida ma di difficile lettura e non evidenzia la relazione tra le tre proprietà di replica. L’implementazione di un valutatore di predicati personalizzato ridurrà la complessità e migliorerà la semantica di questa query.
L'obiettivo della ReplicationPredicateEvaluator
deve supportare la query di cui sopra utilizzando la sintassi seguente.
path=/content
replic.by=admin
replic.since=2013-01-01T00:00:00.000+01:00
replic.action=Activate
Il raggruppamento dei predicati di replica con un valutatore di predicati personalizzato consente di creare una query significativa.
L’avvio di nuovi progetti AEM, compreso l’utilizzo di Maven, è spiegata in dettaglio da l’esercitazione WKND.
Innanzitutto devi aggiornare le dipendenze Maven del progetto. Il PredicateEvaluator
fa parte del cq-search
deve essere aggiunto al file POM Maven.
Ambito di applicazione cq-search
dipendenza impostata su provided
perché cq-search
verrà fornito da OSGi
contenitore.
Lo snippet seguente mostra le differenze nelle pom.xml
file, in formato diff unificato
@@ -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>
Il cq-search
il progetto contiene AbstractPredicateEvaluator
classe astratta. Questa funzione può essere estesa con alcuni passaggi per implementare un valutatore di predicati personalizzato (PredicateEvaluator
).
La procedura seguente spiega come creare un Xpath
espressione per filtrare i dati. Un'altra opzione sarebbe quella di implementare includes
metodo che seleziona i dati in base alle righe. Consulta la Documentazione Java per ulteriori informazioni.
Creare una nuova classe Java che estende com.day.cq.search.eval.AbstractPredicateEvaluator
Annota la tua classe con un @Component
come gli spettacoli di snippet in formato diff unificato
@@ -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 {
}
Il factory
deve essere una stringa univoca che inizia con com.day.cq.search.eval.PredicateEvaluator/
e che termina con il nome del PredicateEvaluator
.
Il nome del PredicateEvaluator
è il nome del predicato, utilizzato per la creazione di query.
Sostituisci:
public String getXPathExpression(Predicate predicate, EvaluationContext context)
Nel metodo di sostituzione si crea un Xpath
espressione basata su Predicate
fornito nell’argomento.
La completa implementazione di questo PredicateEvaluator
potrebbe essere simile alla classe seguente.
/*
* #%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 ");
}
}
}