Cet article porte sur la configuration des index dans AEM 6. Pour connaître les bonnes pratiques sur l’optimisation des requêtes et l’indexation des performances, consultez les Bonnes pratiques relatives aux requêtes et à l’indexation.
Contrairement à Jackrabbit 2, Oak n’indexe pas le contenu par défaut. Des index personnalisés doivent être créés si nécessaire, comme pour les bases de données relationnelles classiques. S’il n’existe aucun index pour une requête spécifique, plusieurs nœuds seront probablement parcourus. La requête peut toujours fonctionner, mais sera probablement très lente.
Si Oak rencontre une requête sans index, un message de journal de niveau WARN s’affiche :
*WARN* Traversed 1000 nodes with filter Filter(query=select ...) consider creating an index or changing the query
Le moteur de requête Oak prend en charge les langages suivants :
Le backend basé sur Apache Oak permet aux différents indexeurs d’être branchés au référentiel.
Un l’indexeur est l’index des propriétés, pour lequel la définition d’index est stockée dans le référentiel.
Les implémentations d’Apache Lucene et Solr sont également disponibles par défaut, et prennent en charge l’indexation du texte intégral.
L’indexation transversale est utilisé si aucun autre indexeur n’est disponible. Cela signifie que le contenu n’est pas indexé et que les nœuds de contenu sont parcourus pour trouver des correspondances à la requête.
Si plusieurs indexeurs sont disponibles pour une requête, chaque indexeur disponible calcule le coût d’exécution de la requête. Oak sélectionne ensuite l’indexeur avec le coût estimé le plus bas.
Le diagramme ci-dessus est une représentation de haut niveau du mécanisme d’exécution des requêtes Apache Oak.
D’abord, la requête est analysée dans une arborescence de syntaxe abstraite. Ensuite, la requête est vérifiée et transformée en SQL-2, qui est le langage natif des requêtes Oak.
Ensuite, chaque index est consulté pour estimer le coût de la requête. Une fois cette étape terminée, les résultats de l’index le plus économique sont récupérés. Enfin, les résultats sont filtrés, pour garantir que l’utilisateur actuel bénéficie de l’accès en lecture au résultat, et que le résultat correspond à la requête complète.
Pour un référentiel de grande taille, créer un index est une opération qui demande beaucoup de temps. Cela vaut aussi bien pour la création initiale d’un index que pour la réindexation (reconstruction d’un index après avoir modifié la définition). Consultez également les sections Résolution des problèmes liés aux index Oak et Empêcher une réindexation lente.
Si une réindexation s’avère nécessaire dans des référentiels très volumineux, en particulier lorsque vous utilisez MongoDB et des index en texte intégral, pensez à recourir à la pré-extraction de texte, ainsi qu’à utiliser la commande oak-run pour générer l’index initial et procéder à la réindexation.
Les index sont configurés en tant que nœuds dans le référentiel sous le nœud oak:index.
Le type du nœud d’index doit être oak:QueryIndexDefinition. Plusieurs options de configuration sont disponibles pour chaque indexeur en tant que propriétés de nœud. Pour plus d’informations, voir les détails de configuration pour chaque type d’indexeur ci-dessous.
L’index de propriété est généralement utile pour les requêtes limitées par la propriété, mais qui ne sont pas en texte intégral. Il peut être configuré en suivant la procédure ci-dessous :
Ouvrez CRXDE en accédant à http://localhost:4502/crx/de/index.jsp
.
Créez un nœud sous oak:index
Nommez le nœud PropertyIndex, puis définissez le type de nœud sur oak:QueryIndexDefinition
Définissez les propriétés suivantes pour le nouveau nœud :
property
(de type String)jcr:uuid
(de type Nom)Cet exemple particulier indexera la propriété jcr:uuid
, dont la tâche est de présenter l’UUID (universally unique identifier) du nœud associé.
Enregistrez les modifications.
L’index de propriété dispose des options de configuration suivantes :
La propriété type spécifie le type d’index. Dans ce cas, il doit être défini sur property.
La propriété propertyNames indique la liste des propriétés qui seront stockées dans l’index. Si ces informations sont manquantes, le nom du noeud sera utilisé comme valeur de référence pour le nom de propriété. Dans cet exemple, la propriété jcr:uuid, dont la tâche est de présenter l’UUID (universally unique identifier) de son nœud, est ajoutée à l’index.
L’indicateur unique, qui, défini sur true, ajoute une limite d’unicité à l’index de propriété.
La propriété declaringNodeTypes vous permet de spécifier un certain type de nœud que l’index appliquera uniquement.
L’indicateur reindex, si défini sur true, déclenchera une réindexation de l’ensemble du contenu.
L’index organisé est une extension de l’index de propriété. Toutefois, il est obsolète. Les index de ce type doivent être remplacés par l’index de propriété Lucene ci-dessous.
L’indexeur de texte intégral basé sur Apache Lucene est disponible dans AEM 6.
Si un index de texte intégral est configuré, alors toutes les requêtes présentant une situation de texte intégral utilisent l’index de texte intégral, qu’il y ait d’autres états indexés ou pas, qu’il existe une restriction de chemin ou pas.
Si aucun index de texte intégral n’est configuré, les requêtes avec des situations de texte intégral ne fonctionneront pas comme prévu.
Étant donné que l’index est mis à jour par le biais d’un thread asynchrone d’arrière-plan, certaines recherches de texte intégral ne seront pas disponibles pendant une courte durée, jusqu’à ce que les processus d’arrière-plan soient terminés.
Vous pouvez configurer un index de texte intégral Lucene en suivant la procédure ci-dessous :
Ouvrez CRXDE et créez un nœud sous oak:index.
Nommez le nœud LuceneIndex et définissez le type de nœud sur oak:QueryIndexDefinition
Ajoutez les propriétés suivantes au nœud :
lucene
(de type String)async
(de type String)Enregistrez les modifications.
L’index Lucene présente les options de configuration suivantes :
Depuis Oak 1.0.8, Lucene peut être utilisé pour créer des indexes qui impliquent des limites de propriété qui ne sont pas du texte intégral.
Pour obtenir un index de propriété Lucene, la propriété fulltextEnabled doit toujours être définie sur false.
Considérez l’exemple de requête suivant :
select * from [nt:base] where [alias] = '/admin'
Pour définir un de propriété Lucene pour la requête ci-dessus, vous pouvez ajouter la définition suivante en créant un nœud sous oak:index:.
LucenePropertyIndex
oak:QueryIndexDefinition
Une fois que le nœud a été créé, ajoutez les propriétés suivantes :
type :
lucene (of type String)
async :
async (of type String)
fulltextEnabled :
false (of type Boolean)
includePropertyNames : [alias]
(de type Chaîne)
Par rapport à l’index standard de propriété, l’index de propriété Lucene est toujours configuré en mode asynchrone. Par conséquent, les résultats renvoyés par l’index peuvent ne pas toujours refléter la version la plus récente du référentiel.
Pour obtenir des informations plus détaillées sur l’index de propriété Lucene, reportez-vous à la page de documentation Oak Lucene Apache Jackrabbit.
Depuis la version 1.2.0, Oak prend en charge les analyseurs Lucene.
Les analyseurs sont utilisés lorsqu’un document est indexé, au moment de la requête. Un analyseur examine le texte des champs et génère un flux de jeton. Les analyseurs Lucene se composent de séries de jetons et de classes de filtres.
Les analyseurs peuvent être configurées par l’intermédiaire du nœud analyzers
(de type nt:unstructured
), à l’intérieur de la définition oak:index
.
L’analyseur par défaut pour un index est configuré dans l’enfant default
du nœud des analyseurs.
Pour obtenir une liste des analyseurs disponibles, veuillez consulter la documentation des API de la version Lucene que vous utilisez.
Si vous souhaitez utiliser l’analyseur prêt à l’emploi, vous pouvez le configurer en suivant la procédure ci-dessous :
Localisez l’index avec lequel vous souhaitez utiliser l’analyseur sous le nœud oak:index
.
Dans l’index, créez un nœud enfant appelé default
de type nt:unstructured
.
Ajoutez une propriété au nœud par défaut avec les propriétés suivantes :
class
String
org.apache.lucene.analysis.standard.StandardAnalyzer
La valeur est le nom de la classe d’analyseur que vous souhaitez utiliser.
Vous pouvez également définir l’analyseur à utiliser avec une version spécifique de Lucene à l’aide de la propriété de chaîne facultative luceneMatchVersion
. Une syntaxe valide pour l’utiliser avec Lucene 4.7 serait :
luceneMatchVersion
String
LUCENE_47
Si luceneMatchVersion
n’est pas spécifié, Oak utilise la version Lucene avec laquelle il est envoyée.
Si vous souhaitez ajouter un fichier de mots vides aux configurations de l’analyseur, vous pouvez créer un nouveau nœud sous le nœud default
avec les propriétés suivantes :
stopwords
nt:file
Les analyseurs peuvent également être classés en fonction de Tokenizers
, TokenFilters
et CharFilters
. Vous pouvez effectuer cette opération en spécifiant un programme d’analyse et en créant des nœuds enfants de ces jetons et filtres facultatifs, qui seront appliqués dans l’ordre indiqué. Consultez également https://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters#Specifying_an_Analyzer_in_the_schema
Prenez cette structure de nœud comme exemple :
Nom : analyzers
Nom : default
Nom : charFilters
Type : nt:unstructured
HTMLStrip
Mapping
Nom : tokenizer
Nom de la propriété : name
String
Standard
Nom : filters
Type : nt:unstructured
Nom : LowerCase
Nom : Stop
Nom de la propriété : words
String
stop1.txt, stop2.txt
Nom : stop1.txt
nt:file
Nom : stop2.txt
nt:file
Les noms de filtres, charFilters et jetons sont créés en supprimant les suffixes de fabrique. Ainsi :
org.apache.lucene.analysis.standard.StandardTokenizerFactory
devient standard
;
org.apache.lucene.analysis.charfilter.MappingCharFilterFactory
devient Mapping
;
org.apache.lucene.analysis.core.StopFilterFactory
devient Stop
;
Tout paramètre de configuration requis pour la fabrique est spécifié en tant que propriété du noeud en question.
Dans des cas tels que le chargement de mots vides quand le contenu des fichiers externes doit être chargé, le contenu peut être diffusé en créant un nœud enfant nt:file
pour le fichier en question.
L’objectif de l’index Solr est principalement la recherche de texte intégral, mais il peut également être utilisé pour indexer par chemin, limite de propriété et restrictions de type principal. Cela signifie que l’index Solr dans Oak peut être utilisé pour n’importe quel type de requête JCR.
L’intégration dans AEM se produit au niveau du référentiel. Ainsi, Solr est l’un des index pouvant être utilisés dans Oak, la nouvelle implémentation de référentiel fournie avec AEM.
AEM peut également être configuré pour travailler avec une instance de serveur distant Solr :
Téléchargez et extrayez la version la plus récente de Solr. Pour plus d’informations sur la façon de procéder, consultez la documentation d’installation Apache Solr.
Créez deux partitions Solr. Pour ce faire, vous devez créer des dossiers pour chaque partition dans le dossier dans lequel Solr a été décompressé :
<solrunpackdirectory>\aemsolr1\node1
<solrunpackdirectory>\aemsolr2\node2
Recherchez un exemple d’instance dans le module Solr. Cet environnement se situe généralement dans un dossier nommé « example
» dans la racine du module.
Copiez les dossiers suivants de l’instance d’exemple vers les deux dossiers des partitions (aemsolr1\node1
et aemsolr2\node2
) :
contexts
etc
lib
resources
scripts
solr-webapp
webapps
start.jar
Créez un dossier appelé « cfg
» dans chacun des deux dossiers des partitions.
Définissez vos fichiers de configuration Solr et Zookeeper dans les dossiers nouvellement créés cfg
.
Pour plus d’informations sur la configuration de Solr et ZooKeeper, consultez la documentation sur la configuration de Solr et le Guide de prise en main pour ZooKeeper.
Démarrez la première partition avec la prise en charge de ZooKeeper en accédant à aemsolr1\node1
et en exécutant la commande suivante :
java -Xmx2g -Dbootstrap_confdir=./cfg/oak/conf -Dcollection.configName=myconf -DzkRun -DnumShards=2 -jar start.jar
Démarrez la deuxième partition en accédant à aemsolr2\node2
et en exécutant la commande suivante :
java -Xmx2g -Djetty.port=7574 -DzkHost=localhost:9983 -jar start.jar
Une fois les deux partitions démarrées, vérifiez que tout est en état de marche en vous connectant à l’interface à l’adresse http://localhost:8983/solr/#/
.
Démarrez AEM et accédez à la console web à l’adresse http://localhost:4502/system/console/configMgr
.
Définissez la configuration suivante dans la configuration du serveur distant Solr Oak :
http://localhost:8983/solr/
Sélectionnez Solr distant dans la liste déroulante sous le fournisseur de serveurs Oak Solr.
Accédez à CRXDE et connectez-vous en tant qu’administrateur.
Créez un nœud appelé solrIndex sous oak:index et définissez les propriétés suivantes :
Enregistrez les modifications.
Voici un exemple de configuration de base qui peut être utilisée avec les trois déploiements Solr décrits dans cet article. Il s’adapte aux index de propriété dédiés qui sont déjà présents dans AEM et ne doivent pas être utilisés avec d’autres applications.
Pour l’utiliser correctement, vous devez placer le contenu de l’archive directement dans le répertoire d’accueil Solr. Dans le cas de déploiements avec plusieurs nœuds, il doit être placé directement sous le dossier racine de chaque nœud.
Fichiers de configuration recommandés pour Solr
AEM 6.1 intègre également deux outils d’indexation présents dans AEM 6.0 dans le cadre de l’ensemble d’outils d’Adobe Consulting Services Commons :
Vous pouvez désormais y accéder en vous rendant dans Outils - Opérations - Tableau de bord- Diagnostic à partir de l’écran de bienvenue d’AEM.
Pour plus d’informations sur la manière de les utiliser, reportez-vous à la documentation du tableau de bord des opérations.
Les modules ACS Commons présentent également des configurations OSGi qui peuvent être utilisées pour créer des index de propriété.
Vous pouvez y accéder à partir de la console web en recherchant « Ensure Oak Property Index » (Assurer l’index de propriété Oak).
Vous pouvez être confronté à des situations au cours desquelles les requêtes prennent du temps à s’exécuter et le délai de réponse système est lent.
Cette section présente un ensemble de recommandations sur la marche à suivre pour trouver la cause de ces problèmes et présente des conseils sur la manière d’y remédier.
La façon la plus simple d’obtenir les informations requises pour la requête en cours d’exécution est via l’outil Explain Query. Il vous permet de collecter les informations nécessaires pour corriger une requête lente sans avoir besoin de consulter les informations au niveau du journal. Cette méthode est préférable si vous connaissez la requête qui est en cours de débogage.
Si cela n’est pas possible pour une raison quelconque, vous pouvez rassembler les journaux d’indexation dans un seul fichier, puis les utiliser pour résoudre votre problème particulier.
Pour activer la journalisation, vous devez activer les journaux de niveau DEBUG pour les catégories concernant l’indexation et les requêtes Oak. Ces catégories sont les suivantes :
La catégorie com.day.cq.search s’applique uniquement si vous utilisez l’utilitaire QueryBuilder fourni par AEM.
Il est important que les journaux soient uniquement définis sur DEBUG pendant que la requête que vous voulez résoudre est en cours d’exécution, sinon un grand nombre d’événements seront générés dans les journaux au fil du temps. Pour cette raison, une fois que les journaux requis sont collectés, revenez à la journalisation au niveau INFO pour les catégories mentionnées ci-dessus.
Vous pouvez activer la journalisation en suivant cette procédure :
Pointez votre navigateur sur https://serveraddress:port/system/console/slinglog
.
Cliquez sur le bouton Ajouter un nouvel enregistreur dans la partie inférieure de la console.
Dans la ligne que vous venez de créer, ajoutez les catégories mentionnées ci-dessus. Vous pouvez utiliser le signe + pour ajouter plus d’une catégorie à un seul journal.
Sélectionnez DÉBOGUER dans la liste déroulante Niveau de journal.
Définissez le fichier de sortie sur logs/queryDebug.log
. Cela corrélera tous les événements DÉBOGUER dans un seul fichier journal.
Exécutez la requête ou effectuez le rendu de la page qui utilise la requête que vous souhaitez déboguer.
Une fois que vous avez exécuté la requête, revenez à la console de journalisation et modifiez le niveau du journal nouvellement créé en le passant sur INFO.
La façon dont la requête est évaluée est largement affectée par la configuration de l’index. Il est donc important d’obtenir la configuration d’index pour l’analyser ou l’envoyer à l’assistance. Vous pouvez obtenir la configuration en tant que module de contenu ou en tant que rendu JSON.
Comme dans la plupart des cas, la configuration d’indexation est stockée dans le nœud /oak:index
dans CRXDE, vous pouvez obtenir la version JSON à l’adresse :
https://serveraddress:port/oak:index.tidy.-1.json
Si l’index est configuré à un emplacement différent, modifiez le chemin en conséquence.
Dans certains cas, il s’avère utile de fournir la sortie des MBeans liés à l’index pour le débogage. Vous pouvez le faire en procédant comme suit :
Accédez à la console JMX à l’adresse :
https://serveraddress:port/system/console/jmx
Recherches les MBeans suivants :
Cliquez sur chacun des MBeans pour obtenir les statistiques de performances. Créez une capture d’écran ou notez-les au cas où vous devez les envoyer au service d’assistance.
Vous pouvez également obtenir la variante JSON de ces statistiques en accédant aux URL suivantes :
https://serveraddress:port/system/sling/monitoring/mbeans/org/apache/jackrabbit/oak/%2522LuceneIndex%2522.tidy.-1.json
https://serveraddress:port/system/sling/monitoring/mbeans/org/apache/jackrabbit/oak/%2522LuceneIndex%2522.tidy.-1.json
https://serveraddress:port/system/sling/monitoring/mbeans/org/apache/jackrabbit/oak/%2522LuceneIndex%2522.tidy.-1.json
https://serveraddress:port/system/sling/monitoring/mbeans/org/apache/jackrabbit/oak/%2522LuceneIndex%2522.tidy.-1.json
Vous pouvez également fournir une sortie JMX consolidée via https://serveraddress:port/system/sling/monitoring/mbeans/org/apache/jackrabbit/oak.tidy.3.json
. Cela inclut tous les détails liés à MBean Oak au format JSON.
Vous pouvez rassembler des informations supplémentaires afin de résoudre le problème, par exemple :
org.apache.jackrabbit.oak-core
.https://serveraddress:port/libs/cq/search/content/querydebug.html
.