Oak查询和索引

注意

本文介绍如何在AEM 6中配置索引。 有关优化查询和索引性能的最佳实践,请参阅查询和索引的最佳实践

简介

与Jackrabbit 2不同,Oak默认不为内容编制索引。 需要创建自定义索引,这与传统的关系数据库非常相似。 如果特定查询没有索引,则可能会遍历许多节点。 查询可能仍然有效,但可能非常缓慢。

如果Oak遇到没有索引的查询,将打印一条WARN级别日志消息:

*WARN* Traversed 1000 nodes with filter Filter(query=select ...) consider creating an index or changing the query

支持的查询语言

Oak查询引擎支持以下语言:

  • XPath(推荐)
  • SQL-2
  • SQL(已弃用)
  • JQOM

索引器类型和成本计算

基于Apache Oak的后端允许将不同的索引器插入存储库。

一个索引器是​属性索引,其索引定义存储在存储库本身中。

默认情况下,Apache Lucene​和​Solr​的实现也可用,两者都支持全文索引。

如果没有其他索引器可用,则使用​遍历索引。 这意味着不对内容编制索引,并会遍历内容节点以查找与查询的匹配项。

如果有多个索引器可用于查询,则每个可用的索引器估计执行查询的成本。 然后,Oak以最低的估计成本选择索引器。

chlimage_1-148

上图是Apache Oak查询执行机制的高级表示。

首先,将查询解析为抽象语法树。 然后,检查查询并将其转换为SQL-2,SQL-2是Oak查询的本机语言。

然后,参考每个指数来估计查询的成本。 一旦完成,将检索最便宜指数的结果。 最后,过滤结果,以确保当前用户对结果具有读取访问权限,并且结果与完整查询匹配。

配置索引

注意

对于大型存储库,构建索引是一项耗时的操作。 对于索引的初始创建和重新索引(在更改定义后重建索引),都是如此。 另请参阅Oak索引疑难解答防止慢速重新索引

如果在大型存储库中需要重新索引,尤其是在使用MongoDB和全文索引时,请考虑文本预提取,并使用oak-run构建初始索引和重新索引。

索引在存储库的​oak:index​节点下配置为节点。

索引节点的类型必须为​oak:QueryIndexDefinition。 每个索引器都有若干配置选项作为节点属性。有关详细信息,请参阅下面每个索引器类型的配置详细信息。

属性索引

属性索引通常适用于具有属性约束但不是全文的查询。 可以按照以下过程进行配置:

  1. 转到http://localhost:4502/crx/de/index.jsp打开CRXDE

  2. 在​oak:index​下创建新节点

  3. 将节点命名为​PropertyIndex,并将节点类型设置为​oak:QueryIndexDefinition

  4. 为新节点设置以下属性:

    • type: property (类型为字符串)
    • propertyNames: jcr:uuid (类型为Name)

    此特定示例将索引jcr:uuid属性,其工作是公开其所连接节点的全局唯一标识符(UUID)。

  5. 保存更改。

属性索引具有以下配置选项:

  • type​属性将指定索引类型,在这种情况下,必须将其设置为​property

  • propertyNames​属性指示将存储在索引中的属性的列表。 如果缺少,则节点名称将用作属性名称引用值。 在此示例中,将其作业是公开其节点的唯一标识符(UUID)的​jcr:uuid​属性添加到索引中。

  • 如果设置为​true,则​unique​标志将为属性索引添加唯一性约束。

  • clainingNodeTypes​属性允许您指定索引将仅应用到的特定节点类型。

  • 如果将​true​设置为,则​重新索引​标志将触发完全内容重新索引。

有序索引

Ordered索引是属性索引的扩展。 但是,它已弃用。 此类型的索引需要替换为Lucene属性索引

Lucene全文索引

AEM 6中提供基于Apache Lucene的全文索引器。

如果配置了全文索引,则所有具有全文条件的查询都使用全文索引,无论是否有其他条件进行索引,也无论是否存在路径限制。

如果未配置全文索引,则具有全文条件的查询将无法按预期工作。

由于索引是通过异步背景线程更新的,因此一些全文搜索在一小段时间内将不可用,直到后台进程完成。

您可以按照以下过程配置Lucene全文索引:

  1. 打开CRXDE并在​oak:index​下创建新节点。

  2. 将节点命名为​LuceneIndex,并将节点类型设置为​oak:QueryIndexDefinition

  3. 向节点添加以下属性:

    • type: lucene (类型为字符串)
    • async: async (属于字符串类型)
  4. 保存更改。

Lucene Index具有以下配置选项:

  • 必须指定索引类型的​type​属性必须设置为​lucene
  • async​属性,必须设置为​async。 这会将索引更新过程发送到后台线程。
  • includePropertyTypes​属性,它将定义索引中将包含哪些属性类型子集。
  • excludePropertyNames​属性,它将定义属性名称的列表-应从索引中排除的属性。
  • 当设置为​true​时,重新索引​标志会触发完全内容重新索引。

Lucene属性索引

由于​Oak 1.0.8,Lucene可用于创建包含非全文的属性约束的索引。

要获得Lucene属性索引,fulltextEnabled​属性必须始终设置为false。

以下示例查询:

select * from [nt:base] where [alias] = '/admin'

为了为上述查询定义Lucene属性索引,您可以通过在​oak:index:​下创建新节点来添加以下定义

  • 名称: LucenePropertyIndex
  • 类型: oak:QueryIndexDefinition

创建节点后,添加以下属性:

  • 类型:

    lucene (of type String)
    
  • 异步:

    async (of type String)
    
  • fulltextEnabled:

    false (of type Boolean)
    
  • includePropertyNames: [alias] (类型为字符串)

注意

与常规属性索引相比,Lucene属性索引始终以异步模式配置。 因此,索引返回的结果可能并不总是反映存储库的最新状态。

注意

有关Lucene属性索引的详细信息,请参阅Apache Jackrabbit Oak Lucene文档页面

Lucene分析器

自版本1.2.0起,Oak支持Lucene分析器。

在编制文档索引时和在查询时都使用分析器。 分析器检查字段文本并生成令牌流。 Lucene分析器由一系列标记器和过滤器类组成。

可以通过oak:index定义内的analyzers节点(类型nt:unstructured)配置分析器。

索引的默认分析器在分析器节点的default子级中配置。

chlimage_1-149

注意

有关可用分析器的列表,请查阅您所使用的Lucene版本的API文档。

直接指定Analyzer类

如果您希望使用任何现成的分析器,可以按照以下过程进行配置:

  1. oak:index节点下找到要使用分析器的索引。

  2. 在索引下,创建一个名为default的子节点,类型为nt:unstructured

  3. 使用以下属性向默认节点添加属性:

    • 名称: class
    • 类型: String
    • 值: org.apache.lucene.analysis.standard.StandardAnalyzer

    值是您要使用的分析器类的名称。

    还可以使用可选的luceneMatchVersion字符串属性设置要与特定lucene版本一起使用的分析器。 与Lucene 4.7一起使用它的有效合成是:

    • 名称: luceneMatchVersion
    • 类型: String
    • 值: LUCENE_47

    如果未提供luceneMatchVersion,Oak将使用随附的Lucene版本。

  4. 如果要向分析器配置添加秒词文件,可以在default下创建一个具有以下属性的新节点:

    • 名称: stopwords
    • 类型: nt:file

通过合成创建分析器

分析器也可基于TokenizersTokenFiltersCharFilters进行组成。 为此,可指定分析器并创建其可选标记器和过滤器的子节点,这些子节点将按列出顺序应用。 另请参阅https://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters#Specifying_an_Analyzer_in_the_schema

以此节点结构为例:

  • 名称: analyzers

    • 名称: default

      • 名称: charFilters

      • 类型: nt:unstructured

        • 名称: HTMLStrip
        • 名称: Mapping
      • 名称: tokenizer

        • 属性名称: name

          • 类型: String
          • 值: Standard
      • 名称: filters

      • 类型: nt:unstructured

        • 名称: LowerCase

        • 名称: Stop

          • 属性名称: words

            • 类型: String
            • 值: stop1.txt, stop2.txt
          • 名称: stop1.txt

            • 类型: nt:file
          • 名称: stop2.txt

            • 类型: nt:file

过滤器、charFilters和标记器的名称通过删除工厂后缀来形成。 因此:

  • org.apache.lucene.analysis.standard.StandardTokenizerFactory 变成 standard

  • org.apache.lucene.analysis.charfilter.MappingCharFilterFactory 变成 Mapping

  • org.apache.lucene.analysis.core.StopFilterFactory 变成 Stop

工厂所需的任何配置参数都指定为相关节点的属性。

对于加载需要加载外部文件内容的停止词等情况,可以通过为相关文件创建nt:file类型的子节点来提供内容。

索尔指数

Solr索引的主要用途是全文搜索,但也可用于按路径、属性限制和主要类型限制对搜索进行索引。 这意味着Oak中的Solr指数可用于任何类型的JCR查询。

AEM中的集成在存储库级别进行,因此Solr是Oak中可能使用的索引之一,Oak是随AEM一起提供的新存储库实施。

它可以配置为作为具有AEM实例的嵌入式服务器或作为远程服务器工作。

使用嵌入的Solr服务器配置AEM

注意

请勿在生产环境中使用嵌入式Solr服务器。 它只应用于开发环境。

AEM可与嵌入式Solr服务器一起使用,该服务器可通过Web控制台进行配置。 在这种情况下,Solr服务器将与其嵌入的AEM实例在相同的JVM中运行。

您可以通过以下方式配置嵌入式Solr服务器:

  1. 转到位于https://serveraddress:4502/system/console/configMgr的Web控制台

  2. 搜索“Oak Solr服务器提供商”。

  3. 按编辑按钮,在下拉列表中将服务器类型设置为​嵌入式Solr

  4. 然后,编辑“Oak Solr嵌入式服务器配置”并创建配置。 有关配置选项的详细信息,请访问Apache Solr网站

    注意

    Solr主目录(solr.home.path)配置将在AEM安装文件夹中查找名称相同的文件夹。

  5. 打开CRXDE并以管理员身份登录。

  6. 在​oak:index​下添加名为​solrlndex​的​oak:QueryIndexDefinition​类型的节点,其属性如下:

    • type: solr(类型为字符串)
    • async: async(属于字符串类型)
    • 重新索引 true:(类型为布尔型)
  7. 保存更改。

使用单个远程Solr服务器配置AEM

AEM还可以配置为与远程Solr服务器实例一起使用:

  1. 下载并提取最新版Solr。 有关如何执行此操作的详细信息,请参阅Apache Solr安装文档

  2. 现在,创建两个索尔碎片。 为此,可以在Solr已隐藏的文件夹中为每个共享创建文件夹:

    • 对于第一个共享,创建文件夹:

    <solrunpackdirectory>\aemsolr1\node1

    • 对于第二个共享,请创建文件夹:

    <solrunpackdirectory>\aemsolr2\node2

  3. 在Solr包中找到示例实例。 它通常位于包根目录中名为“ example”的文件夹中。

  4. 将示例实例中的以下文件夹复制到两个共享文件夹(aemsolr1\node1aemsolr2\node2):

    • contexts
    • etc
    • lib
    • resources
    • scripts
    • solr-webapp
    • webapps
    • start.jar
  5. 在两个共享文件夹中的每个文件夹中新建一个名为“ cfg”的文件夹。

  6. 将Solr和Zookeeper配置文件放入新创建的cfg文件夹中。

    注意

    有关Solr和ZooKeeper配置的详细信息,请参阅Solr配置文档ZooKeeper入门指南

  7. 开始支持ZooKeeper的第一个共享区,方法是转到aemsolr1\node1并运行以下命令:

    java -Xmx2g -Dbootstrap_confdir=./cfg/oak/conf -Dcollection.configName=myconf -DzkRun -DnumShards=2 -jar start.jar
    
  8. 开始第二个共享,方法是转到aemsolr2\node2并运行以下命令:

    java -Xmx2g -Djetty.port=7574 -DzkHost=localhost:9983 -jar start.jar
    
  9. 启动两个分片后,通过连接到http://localhost:8983/solr/#/的Solr接口,测试一切是否已启动并运行

  10. 开始AEM并转到位于http://localhost:4502/system/console/configMgr的Web控制台

  11. 在​Oak Solr远程服务器配置​下设置以下配置:

    • 解析HTTP URL:http://localhost:8983/solr/
  12. 在​Oak Solr​服务器提供商下的下拉列表下选择​远程Solr

  13. 转到CRXDE并以管理员身份登录。

  14. 在​oak:index​下新建一个名为​solrIndex​的节点,并设置以下属性:

    • type:​solr(字符串类型)
    • async:​async(字符串类型)
    • 重新索引:​true(布尔类型)
  15. 保存更改。

下面是一个基本配置的示例,它可用于本文中描述的所有三个Solr部署。 它包含AEM中已存在的专用属性索引,不应与其他应用程序一起使用。

为了正确使用它,您需要将存档的内容直接放在Solr Home Directory中。 在多节点部署的情况下,它应直接位于每个节点的根文件夹下。

推荐的Solr配置文件

获取文件

AEM索引工具

AEM 6.1还集成了AEM 6.0中提供的两个索引工具,作为Adobe咨询服务公共工具集的一部分:

  1. 解释查询,这是一种旨在帮助管理员了解查询如何执行的工具;
  2. Oak Index Manager,用于维护现有索引的Web用户界面。

现在,您可以从AEM欢迎屏幕转到​工具——操作-仪表板-诊断​来访问它们。

有关如何使用它们的详细信息,请参阅操作仪表板文档

通过OSGi创建属性索引

ACS Commons包还公开可用于创建属性索引的OSGi配置。

您可以通过搜索“Ensure Oak Property Index”从Web控制台访问它。

chlimage_1-150

索引问题疑难解答

查询执行时间较长,且一般系统响应时间较慢的情况可能会出现。

本节提出了一系列建议,说明需要采取哪些措施来查明这些问题的原因,并就如何解决这些问题提出了建议。

准备分析的调试信息

要获取所执行查询的所需信息,最简单的方法是通过解释查询工具。 这样,您就可以收集调试速度较慢的查询所需的精确信息,而无需查阅日志级别信息。 如果您知道正在调试的查询,这是理想的。

如果由于任何原因无法实现此目的,您可以将索引日志收集到单个文件中,并使用它解决您的特定问题。

启用日志记录

要启用日志记录,您需要为与Oak索引和查询相关的类别启用​DEBUG​级别日志。 这些类别是:

  • org.apache.jackrabbit.oak.plugins.index
  • org.apache.jackrabbit.oak.query
  • com.day.cq.search

com.day.cq.search​类别仅在您使用AEM提供的QueryBuilder实用程序时适用。

注意

在执行要排除故障的查询期间,日志只设置为DEBUG,这一点很重要,否则随着时间的推移,日志中将生成大量事件。 因此,一旦收集到所需日志,就会切换回上述类别的“信息”级别日志记录。

您可以通过以下过程启用日志记录:

  1. 将浏览器指向https://serveraddress:port/system/console/slinglog

  2. 单击控制台下半部分的​添加新Logger​按钮。

  3. 在新创建的行中,添加上述类别。 可以使用​+​符号向单个记录器添加多个类别。

  4. 从​日志级别​下拉列表中选择​DEBUG

  5. 将输出文件设置为logs/queryDebug.log。 这会将所有调试事件关联到单个日志文件中。

  6. 运行查询或呈现使用要调试的查询的页面。

  7. 执行查询后,返回日志记录控制台,将新创建的记录器的日志级别更改为​INFO

索引配置

查询的评估方式在很大程度上受索引配置的影响。 获得索引配置对于分析或发送给支持非常重要。 您可以将配置作为内容包获取或获取JSON再现。

由于大多数情况下,索引配置存储在CRXDE的/oak:index节点下,因此您可以在以下位置获得JSON版本:

https://serveraddress:port/oak:index.tidy.-1.json

如果在其他位置配置索引,请相应地更改路径。

MBean输出

在某些情况下,提供与索引相关的MBean的输出以进行调试很有帮助。 可通过以下方式执行此操作:

  1. 转到JMX控制台:
    https://serveraddress:port/system/console/jmx

  2. 搜索以下MBean:

    • Lucene指数统计
    • CopyOnRead支持统计
    • Oak查询统计
    • IndexStats
  3. 单击每个MBean以获取性能统计信息。 创建屏幕截图或记下它们,以备需要提交支持。

您还可以在以下URL获取这些统计信息的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
  • 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.tidy.3.json提供统一的JMX输出。 这将包括JSON格式的所有与Oak相关的MBean详细信息。

其他详细信息

您可以收集其他详细信息以帮助解决问题,例如:

  1. 您的实例正在运行的Oak版本。 打开CRXDE并查看欢迎页面右下角的版本,或检查org.apache.jackrabbit.oak-core捆绑包的版本,即可看到这一点。
  2. 麻烦查询的QueryBuilder调试器输出。 调试器可在以下位置访问:https://serveraddress:port/libs/cq/search/content/querydebug.html

在此页面上