クエリとインデックスに関するベストプラクティス

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

AEM 6 での Oak への移行に伴い、クエリとインデックスの管理方法に関して大きな変更がいくつか導入されました。Jackrabbit 2 では、すべてのコンテンツはデフォルトでインデックス付けされ、自由に照会できます。 Oak では、oak:index ノードの下にインデックスを手動で作成する必要があります。クエリはインデックスなしで実行できますが、大きなデータセットの場合は実行に時間がかかり、中止することもできます。

この記事では、インデックスを作成するタイミングと不要な場合の概要、クエリが不要な場合の使用を回避するためのテクニック、可能な限り最適に実行するためのインデックスとクエリの最適化に関するヒントについて説明します。

また、必ず クエリとインデックスの作成に関する Oak ドキュメント. AEM 6 における新しい概念であるインデックスに加えて、Oak クエリの構文も大きく異なります。以前の AEM インストールからコードを移行する際にはこの違いを考慮する必要があります。

クエリを使用する場面

リポジトリと分類の設計

リポジトリの分類を設計する際は、いくつかの要因を考慮する必要があります。これには、アクセス制御、ローカライゼーション、コンポーネント、ページプロパティの継承などが含まれます。

こうした事柄に対応する分類を設計する一方で、インデックス設計の「トラバーサビリティ」についても検討することも重要です。トラバーサビリティとは、この文脈では、パスに基づいて予想どおりにコンテンツにアクセスできるようにする分類の機能を言います。これにより、多数のクエリを実行する場合よりも保守が容易な、よりパフォーマンスの高いシステムが実現します。

また、分類を設計する際は、順序が重要かどうかを考慮することが重要です。 明示的な順序が不要で、多くの兄弟ノードが想定される場合は、次のような順序なしのノードタイプを使用することをお勧めします。 sling:Folder または oak:Unstructured. 順序が必要な場合、 nt:unstructured、および sling:OrderedFolder の方が適切です。

コンポーネント内のクエリ

AEMシステムで実行されるクエリは、より負担のかかる操作の 1 つになる可能性があるので、コンポーネント内でクエリを使用しないことをお勧めします。 ページがレンダリングされるたびに複数のクエリを実行すると、システムのパフォーマンス低下につながります。コンポーネントのレンダリング時にクエリが実行されることを回避するには、ノードの走査​と​結果の先取り​という 2 つの方法があります。

ノードの走査

必要なデータの場所を事前に把握できるようにリポジトリを設計した場合、必要なパスからこのデータを取得するコードをデプロイできます。クエリを実行して検索する必要はありません。

例えば、特定のカテゴリに適合するコンテンツのレンダリングが行われます。1 つの方法として、コンテンツをカテゴリプロパティで整理し、クエリを実行して、カテゴリ内の項目を表示するコンポーネントに入力できるようにします。

より優れた方法は、このコンテンツを手動で取得できるように、カテゴリ別の分類に構造化することです。

例えば、コンテンツが次のような分類に格納されている場合です。

/content/myUnstructuredContent/parentCategory/childCategory/contentPiece

The /content/myUnstructuredContent/parentCategory/childCategory ノードは単に取得でき、その子を解析してコンポーネントのレンダリングに使用できます。

また、小さな結果セットや同種の結果セットを扱う場合は、同じ結果セットを返すクエリを作成するよりも、リポジトリを経由して必要なノードを収集する方が速くなります。 一般的な考慮事項として、クエリはできる限り使用せずに済ませる必要があります。

結果の先取り

コンテンツやコンポーネントの要件によっては、必要なデータを取得する方法としてノードの走査を使用できない場合があります。その場合は、エンドユーザーに最適なパフォーマンスを保証するために、コンポーネントがレンダリングされる前に必要なクエリを実行する必要があります。

コンポーネントで必要とされる結果をオーサリング時にまとめて計算でき、さらにコンテンツがその後も変更されないとわかっている場合は、オーサーがダイアログで設定を適用するときにクエリを実行できます。

データまたはコンポーネントが定期的に変更される場合は、スケジュールに従って、または基礎データの更新リスナーを使用してクエリを実行できます。その後、結果をリポジトリ内の共有場所に書き込むことができます。このデータを必要とするコンポーネントは、実行時にクエリを実行しなくても、この 1 つのノードから値を取り出すことが可能です。

クエリの最適化

インデックスを使用していないクエリを実行すると、ノードトラバーサルに関する警告が記録されます。 このクエリが頻繁に実行されるクエリの場合は、インデックスを作成します。 特定のクエリが使用しているインデックスを確認するには、クエリの説明を実行ツールを推奨します。さらに情報を得るために、関連する検索 API の DEBUG ログを有効にすることもできます。

メモ

インデックス定義を変更した後、インデックスを再構築(再インデックス)する必要があります。 インデックスのサイズによっては、この処理を終えるまでにある程度時間がかかることがあります。

複雑なクエリを実行するときは、クエリを複数の小さなクエリに分割し、後からコードによってデータを結合するほうが、パフォーマンスが向上することがあります。その場合のレコメンデーションは、2 つの方法のパフォーマンスを比較し、当該のユースケースでどちらの選択肢が優れているか確認することです。

AEM では、次の 3 つの方法でクエリを記述できます。

  • QueryBuilder API を使用(推奨)
  • XPath を使用(推奨)
  • SQL2 を使用

すべてのクエリは実行前に SQL2 に変換されますが、クエリ変換のオーバーヘッドはごくわずかなので、クエリ言語を選択するときの主な懸念事項は可読性と開発チームの安心感ということになります。

メモ

QueryBuilder を使用する場合、デフォルトで結果数を決定します。Oak では、以前のバージョンの Jackrabbit に比べて時間がかかります。 これを補うために、guessTotal パラメーターを使用できます。

クエリの説明を実行ツール

任意のクエリ言語と同様に、クエリを最適化する最初の手順は、クエリの実行方法を理解することです。 これをおこなうには、操作ダッシュボードにあるクエリの説明を実行ツールを使用します。このツールを使用すると、クエリにプラグインして説明を取得できます。クエリが大きなリポジトリと実行時に問題を引き起こす場合、および使用されているインデックスに関する警告が表示されます。 このツールでは、低速なクエリやよく使用されるクエリのリストを読み込み、これらを説明および最適化できます。

クエリのための DEBUG ログ

Oak による使用するインデックスの選択方法と、クエリエンジンによるクエリの実際の実行方法に関する追加情報を得るために、DEBUG ログ設定を以下のパッケージに追加できます。

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

クエリのデバッグが完了したら、必ずこのロガーを削除してください。 大量のアクティビティを出力する傾向があり、最終的にはログファイルでディスクがいっぱいになる場合があります。

この方法について詳しくは、ログに関するドキュメントを参照してください。

インデックスの統計

Lucene では、インデックス付きのコンテンツに関する詳細(各インデックス内に存在するドキュメントのサイズと数を含む)を提供する JMX Bean が登録されます。

これを確認するには、JMX コンソール(https://server:port/system/console/jmx)にアクセスしてください。

JMX コンソールにログインしたら、以下を検索します。 Lucene インデックスの統計 見つけるために 他のインデックス統計は、IndexStats MBean にあります。

クエリ統計の場合は、 Oak クエリ統計.

Luke などのツールを使用してインデックスを詳しく調べる場合は、Oak コンソールを使用して NodeStore のインデックスをファイルシステムディレクトリにダンプする必要があります。この方法については、 Lucene ドキュメント.

また、JSON 形式でシステム内のインデックスを抽出できます。これをおこなうには、次にアクセスする必要があります: https://server:port/oak:index.tidy.-1.json

クエリ制限

開発中

の低しきい値の設定 oak.queryLimitInMemory ( 例:10000) と Oak。 queryLimitReads (例えば、5000)を使用し、UnsupportedOperationException をヒットした場合に「The query read more than x nodes…」というメッセージを表示し、高価なクエリを最適化します。

これにより、リソースを大量に消費するクエリ(つまり、インデックスでバックアップされていないクエリや、インデックスのカバーが少ないクエリ)を回避できます。 例えば、100 万個のノードを読み取るクエリでは I/O が増加し、アプリケーションの全体的なパフォーマンスに悪影響が生じます。上述のような制限が原因で失敗するクエリは、分析して最適化する必要があります。

デプロイメント後

  • ログを監視して、大規模なノードの走査やヒープメモリの大量使用を引き起こしているクエリがないかどうかを調べます。

    • *WARN* ... java.lang.UnsupportedOperationException: The query read or traversed more than 100000 nodes. To avoid affecting other tasks, processing was stopped.
    • クエリを最適化して、走査するノードの数を減らします。
  • 大量のヒープメモリ消費をトリガーするクエリがないか、ログを監視します。

    • *WARN* ... java.lang.UnsupportedOperationException: The query read more than 500000 nodes in memory. To avoid running out of memory, processing was stopped
    • クエリを最適化して、ヒープメモリの使用量を減らします。

AEM 6.0 ~ 6.2 では、AEM 起動スクリプトの JVM パラメーターを使用してノードのトラバーサルのしきい値を調整し、大きなクエリによる環境への過負荷を防ぐことができます。

推奨される値は次のとおりです。

  • -Doak.queryLimitInMemory=500000
  • -Doak.queryLimitReads=100000

AEM 6.3 では、上記の 2 つのパラメーターは事前に設定されており、OSGi QueryEngineSettings を使用して保持できます。

詳しくは、https://jackrabbit.apache.org/oak/docs/query/query-engine.html#Slow_Queries_and_Read_Limitsを参照してください。

効率的なインデックス作成のヒント

インデックスを作成する必要がありますか?

インデックスを作成または最適化する際に最初に尋ねる質問は、特定の状況でインデックスが必要かどうかです。 そのクエリを一度またはごくまれにしか実行せず、システムのオフピーク時にバッチ処理で実行する場合は、インデックスを作成しないほうが良い場合があります。

インデックスを作成すると、そのインデックスが付けられたデータを更新するたびに、インデックスも更新する必要が生じます。これはシステムのパフォーマンスに影響を与えるので、インデックスを作成する必要があるのは、必要な場合のみにしてください。

また、インデックスは、インデックス内に含まれるデータが十分に一意で、それを保証できる場合にのみ役立ちます。 ある本のインデックス(索引)と、本が取り上げるトピックを考えてみましょう。テキスト内の一連のトピックにインデックスを作成する場合、通常は数百から数千のエントリが存在します。これにより、ページのサブセットにすばやくジャンプして、探している情報をすばやく見つけることができます。 そのインデックスに 2、3 個のエントリしかなく、それぞれが数百ページを指す場合、インデックスは役に立ちません。 この同じ概念は、データベースインデックスにも当てはまります。一意の値が 2 つだけある場合、インデックスは役に立ちません。 ただし、インデックスが大きすぎて役に立たない場合もあります。 インデックス統計を見るには、上記のインデックス統計を参照してください。

Lucene インデックスとプロパティインデックスのどちらを使用するか

Lucene インデックスは Oak 1.0.9 で導入され、AEM 6 の初回起動時に導入されたプロパティインデックスに対して、強力な最適化を提供します。Lucene インデックスまたはプロパティインデックスのどちらを使用するかを決定する際は、次の点を考慮してください。

  • Lucene インデックスは、プロパティインデックスよりも多くの機能を提供します。例えば、プロパティインデックスでは 1 つのプロパティにしかインデックスを作成できませんが、Lucene インデックスでは多数のプロパティを含めることができます。Lucene インデックスで使用可能なすべての機能について詳しくは、 ドキュメント.
  • Lucene インデックスは非同期です。パフォーマンスが大幅に向上する一方で、リポジトリにデータが書き込まれるタイミングとインデックスが更新されるタイミングとの間に遅延が生じる場合もあります。クエリが 100%の正確な結果を返すことが重要な場合は、プロパティインデックスが必要です。
  • Lucene インデックスは、非同期式という特性上、一意性制約を適用できません。これが必要な場合は、プロパティインデックスを配置する必要があります。

一般に、プロパティインデックスを使用する必要性がない限り、より高いパフォーマンスと柔軟性のメリットを得るために Lucene インデックスを使用することをお勧めします。

Solr インデックス作成

AEMは、デフォルトで Solr のインデックス作成もサポートしています。 これは全文検索をサポートするために使用されますが、任意の種類の JCR クエリをサポートするために使用することもできます。 AEM インスタンスに、検索に負荷がかかるデプロイメント(多数の同時ユーザーを持つ検索主導型 web サイトなど)で必要なクエリの数を処理する CPU 処理能力がない場合は、Solr を検討する必要があります。または、Solr をクローラーベースのアプローチで実装して、プラットフォームのより高度な機能の一部を使用することもできます。

Solr インデックスは、AEM サーバー上で開発環境用に埋め込んで実行するように設定することも、リモートインスタンスにオフロードして、実稼動環境とステージング環境での検索のスケーラビリティを向上させることもできます。オフロード検索を使用するとスケーラビリティが向上しますが、遅延が生じるので、必要な場合を除きお勧めしません。 Solr 統合の設定方法と Solr インデックスの作成方法について詳しくは、Oak クエリとインデックス作成に関するドキュメントを参照してください。

メモ

統合型の Solr 検索アプローチを採用すると、インデックス作成を Solr サーバーにオフロードできます。Solr サーバーのより高度な機能をクローラーベースのアプローチで使用する場合は、追加の設定作業が必要です。

このアプローチの欠点は、デフォルトではAEMクエリが ACL に従うので、ユーザーがアクセスできない結果は非表示になり、Solr サーバーに対する検索を外部化してもこの機能はサポートされないということです。 この方法で検索をオフロードする場合は、ユーザーに見せてはいけない結果を表示していないかを特に注意して確認する必要があります。

このアプローチが適しているユースケースとしては、検索データを複数のソースから集めなければならない場合が考えられます。例えば、AEM上でホストされているサイトと、サードパーティプラットフォーム上でホストされている 2 つ目のサイトがあるとします。 この場合は、両方のサイトのコンテンツをクロールし、その結果を統合インデックスに格納するよう Solr を設定できます。こうすることで、クロスサイト検索が可能になります。

設計上の考慮事項

Lucene インデックスに関する Oak のドキュメントでは、以下のとおり、インデックス設計時の考慮事項をいくつか挙げています。

  • クエリで異なるパス制限が使用される場合は、 evaluatePathRestrictions. これにより、クエリは、指定されたパスの下の結果のサブセットを返し、クエリに基づいて結果をフィルタリングできます。 それ以外の場合は、クエリはリポジトリ内のクエリパラメーターに一致するすべての結果を検索し、パスに基づいてフィルタリングします。

  • クエリで並べ替えを使用する場合は、並べ替えるプロパティの明示的なプロパティ定義を用意し、そのプロパティの orderedtrue に設定します。これにより、結果をインデックス内と同じように並べ替え、クエリ実行時のコストの高い並べ替え操作を節約できます。

  • インデックスには必要なものだけを追加します。不要な機能やプロパティを追加すると、インデックスが増え、パフォーマンスが低下します。

  • プロパティインデックスでは、一意のプロパティ名を使用すると、インデックスのサイズを削減できます。しかし Lucene インデックスでは、統一されたインデックスを実現するために、nodeTypesmixins を使用する必要があります。特定の nodeType または mixin をクエリすると、nt:base をクエリするよりもパフォーマンスが向上します。この方法を使用する場合は、当該の nodeTypesindexRules を定義します。

  • クエリを特定のパスでのみ実行する場合は、そのパスの下でインデックスを作成します。インデックスにリポジトリのルートを含める必要はありません。

  • インデックスを作成するすべてのプロパティが Lucene で可能な限り多くのプロパティ制限をネイティブに評価できるように関連付けられている場合は、1 つのインデックスを使用します。 また、結合を実行する場合でも、1 つのクエリで 1 つのインデックスのみが使用されます。

CopyOnRead

NodeStore がリモートに格納されている場合は、CopyOnRead というオプションを有効にできます。このオプションを指定すると、リモートインデックスが読み込まれたときに、リモートインデックスがローカルファイルシステムに書き込まれます。 このオプションは、こうしたリモートインデックスに対して頻繁に実行されるクエリのパフォーマンス向上に役立ちます。

これは OSGi コンソールの LuceneIndexProvider サービスで設定でき、Oak 1.0.13 の時点ではデフォルトで有効です。

インデックスの削除

インデックスを削除するときは、必ず type プロパティを disabled に設定して一時的にインデックスを無効にしたうえで、実際に削除する前にテストを実施し、アプリケーションが正しく動作するか確認することを推奨します。インデックスは無効の間は更新されないので、再度有効にした場合、インデックスを再作成する必要がある場合は、正しいコンテンツが含まれていない可能性があります。

TarMK インスタンスでプロパティインデックスを削除した後、使用中のディスク領域を再利用するには、コンパクションを実行する必要があります。 Lucene インデックスの場合、実際のインデックスコンテンツは BlobStore に格納されているので、データストアのガベージコレクションが必要になります。

MongoDB インスタンスのインデックスを削除する場合、削除のコストはインデックスのノードの数に比例します。大量のインデックスを削除すると問題が生じることがあるので、インデックスを無効にしてから、メンテナンスウィンドウ中に oak-mongo.js などのツールを使用して削除する方法が推奨されます。データの不整合が生じる可能性があるので、この方法は通常のノードコンテンツには使用しないでください。

メモ

oak-mongo.js について詳しくは、Oak のドキュメントの Command Line Tools のセクションを参照してください。

JCR クエリチートシート

効率的な JCR クエリとインデックス定義を作成できるようにするため、開発時に JCR クエリチートシートをダウンロードして参照用として使用できます。これには QueryBuilder、XPath、SQL-2 のクエリの例が収録されていて、クエリのパフォーマンスの点で異なる動作をする複数のシナリオに対応できます。また、Oak インデックスの作成またはカスタマイズ方法に関するレコメンデーションも収録されています。このチートシートの内容は、AEM 6.5 および AEM as a Cloud Service に適用されます。

インデックス再作成

この節では、 のみ Oak インデックスを再インデックスする受け入れ可能な理由。

以下に説明する理由の外、Oak インデックスの再インデックスを開始すると次のことがおこなわれます not 動作を変更したり問題を解決したりすると、AEM上の負荷が不必要に増加します。

以下の表に示す理由でカバーされない限り、Oak インデックスの再インデックスは避ける必要があります。

メモ

以下の表を参照して、インデックスの再作成が有用かどうかを判断する前に、 常に 確認:

  • クエリが正しいこと
  • クエリが予期したインデックスに解決されること(クエリの説明を実行を使用)
  • インデックス作成プロセスが完了していること

Oak インデックスの設定の変更

Oak インデックスの再インデックスに対して許容できる誤りのない条件は、Oak インデックスの設定が変更された場合のみです。

インデックスの再作成は、AEM全体のパフォーマンスに与える影響を常に適切に考慮して取り組み、アクティビティが低い時間帯やメンテナンス時間帯に実行する必要があります。

以下の節では、発生する可能性がある問題と解決策について詳しく説明します。

プロパティインデックスの定義の変更

  • 適用対象:

  • 症状:

    • プロパティインデックスの定義を更新する前に存在していたノードが結果に見つからない
  • 検証方法:

    • 更新したインデックス定義をデプロイする前に、見つからないノードが作成または変更されていたかどうかを確認します。
    • 見つからないノードのjcr:createdまたはjcr:lastModifiedプロパティをインデックスの変更時間と照合して検証します。
  • 解決方法:

    • 再インデックス lucene 指数

    • または、見つからないノードについて処理(安全な書き込み操作)を行います。

      • 手動処理またはカスタムコードが必要です。
      • 見つからない一連のノードを把握する必要があります。
      • ノードでプロパティを変更する必要があります。

Lucene インデックスの定義の変更

  • 適用対象:

  • 症状:

    • 予期した結果が Lucene インデックスに含まれない
    • インデックス定義の予期される動作がクエリ結果に反映されない
    • インデックス定義に基づいて予期される出力がクエリプランで報告されない
  • 検証方法:

    • Lucene Index 統計 JMX Mbean (LuceneIndex) メソッドを使用して、インデックス定義が変更されたことを確認します。 diffStoredIndexDefinition.
  • 解決方法:

    • 1.6 より前の Oak バージョン:

    • 1.6 以降の Oak バージョン

      • 既存のコンテンツが変更の影響を受けない場合は、更新のみが必要です

        • [oak:queryIndexDefinition]@refresh=true を設定して、Lucene インデックスを更新します。
      • それ以外の場合は、 再インデックス lucene 指数

        • 注意:新しいインデックス再作成がトリガーされるまで、最後に正常なインデックス再作成(または最初のインデックス作成)のインデックス状態が使用されます

エラーと例外の状況

次の表に、Oak インデックスの再インデックスによって問題が解決される、許容できるエラーと例外的な状況を示します。

以下に示す条件に一致しないAEMで問題が発生した場合は、 not 問題が解決しないので、インデックスを再インデックスします。

以下の節では、発生する可能性がある問題と解決策について詳しく説明します。

Lucene インデックスのバイナリが見つからない

  • 適用対象:

  • 症状:

    • 予期した結果が Lucene インデックスに含まれない
  • 検証方法:

    • Lucene インデックスのバイナリが見つからないという例外がエラーログファイルに記録されます。
  • 解決方法:

    • リポジトリ走査チェックを実行します。例:

      http://localhost:4502/system/console/repositorycheck

      リポジトリの走査により(lucene ファイル以外の)他のバイナリが欠落していないか判断

    • Lucene インデックス以外のバイナリが見つからない場合は、バックアップから復元します。

    • それ以外の場合は、 再インデックス すべて lucene インデックス

    • メモ:

      この条件は、データストアの設定が誤っていることを示しており、ANY バイナリ(アセットのバイナリなど)が見つからなくなる可能性があります。

      この場合は、正常であることがわかっている最新のリポジトリバージョンに復元し、見つからないすべてのバイナリを回復します。

Lucene インデックスのバイナリが破損している

  • 適用対象:

  • 症状:

    • 予期した結果が Lucene インデックスに含まれない
  • 検証方法:

    • The AsyncIndexUpdate (5 秒ごとに)失敗し、error.log に例外が記録されます。

      ...a Lucene index file is corrupt...

  • 解決方法:

    • Lucene インデックスのローカルコピーを削除します。

      1. AEM を停止します。
      2. crx-quickstart/repository/indexにある Lucene インデックスのローカルコピーを削除
      3. AEM を再起動します。
    • この手順を実行しても問題が解決せず、AsyncIndexUpdate 例外が引き続き発生する場合は、次の手順に従います。

      1. 再インデックス 誤った指数
      2. さらに、アドビサポートチケットを送ります。

再インデックスの方法

メモ

AEM 6.5 では、 oak-run.jar は ONLY でサポートされているメソッドです。 MongoMK または RDBMK リポジトリのインデックス再作成用。

プロパティインデックスの再インデックス

Lucene プロパティインデックスの再インデックス

  • 用途 再インデックスする oak-run.jar Lucene プロパティインデックス。

  • Lucene プロパティインデックスで async-reindex プロパティを true に Lucene プロパティインデックス

    • [oak:queryIndexDefinition]@reindex-async=true
メモ

前の節では、Oak のインデックス再作成に関するガイダンスを、 Apache Oak ドキュメント AEMのコンテキストで使用されます。

バイナリのテキスト事前抽出

テキスト事前抽出は、分離されたプロセスのデータストアから直接バイナリのテキストを抽出して処理し、抽出されたテキストを後続の Oak インデックスの再インデックス/インデックス作成に直接公開するプロセスです。

  • 展開済みの Oak インデックスを介した全文検索に適合する、抽出可能なテキスト (PDF、Word ドキュメント、PPT、TXT など ) を含む大量のファイル(バイナリ)を含むリポジトリで Lucene インデックスを再作成/インデックスする場合は、Oak テキストの事前抽出を推奨します。 /oak:index/damAssetLucene.
  • テキストの事前抽出は、Lucene インデックスと NOT Oak プロパティインデックスの再/インデックスのみに役立ちます。これは、プロパティインデックスがバイナリからテキストを抽出しないからです。
  • テキストの事前抽出は、テキストの多いバイナリ (PDF、ドキュメント、TXT など ) の全文再インデックス時に大きな悪影響を及ぼしますが、画像のリポジトリは抽出可能なテキストを含まないので、同じ効率を発揮しません。
  • テキストの事前抽出では、全文検索関連のテキストの抽出をより効率的な方法で実行し、消費効率の高い方法で Oak の再インデックス/インデックス作成プロセスに公開します。

テキスト事前抽出を使用できる状況

のインデックス再作成 既存 バイナリ抽出が有効な lucene インデックス

  • インデックス再作成処理 すべて リポジトリ内の候補コンテンツ。フルテキストを抽出するバイナリが多数または複雑な場合、フルテキスト抽出を実行する際の計算負荷が増加します。 テキスト事前抽出では、テキスト抽出の「計算コストが高い作業」が分離されたプロセスに移行され、このプロセスが直接 AEM のデータストアにアクセスするので、AEM におけるオーバーヘッドやリソースの競合が回避されます。

バイナリ抽出が有効になった​新しい Lucene インデックスの AEM へのデプロイメントのサポート

  • 新しいインデックス(バイナリ抽出が有効になった)が AEM にデプロイされると、非同期フルテキストインデックス作成の次回実行時に、すべての候補コンテンツのインデックスが自動的に作成されます。上記のインデックス再作成で説明したのと同じ理由で、AEMに過度の読み込みが発生する場合があります。

テキスト事前抽出を使用できない状況

テキスト事前抽出は、リポジトリに追加された新しいコンテンツには使用できません。また、使用する必要もありません。

リポジトリに追加された新しいコンテンツには、非同期フルテキストインデックス作成プロセスによって、インデックスが必然的かつ増分的に作成されます(デフォルトでは 5 秒ごと)。

AEMの通常の操作(Web UI を使用したアセットのアップロードや、プログラムによるアセットの取り込みなど)では、AEMは、新しいバイナリコンテンツのフルテキストインデックスを自動的かつ増分的に作成します。 データの量は増分であり、比較的少ないので(およそ 5 秒でリポジトリに永続化できるデータの量)、AEM では、全体的なシステムパフォーマンスに影響を及ぼすことなく、インデックス作成時にバイナリからのフルテキスト抽出を実行できます。

テキスト事前抽出を使用するための前提条件

  • フルテキストバイナリ抽出を実行する Lucene インデックスを再インデックスするか、既存のコンテンツのフルテキストインデックスバイナリを使用する新しいインデックスをデプロイします。

  • テキストを事前抽出する元のコンテンツ(バイナリ)がリポジトリ内に存在すること

  • CSV ファイルを生成し、最終的なインデックス再作成を実行するためのメンテナンスウィンドウ

  • Oak バージョン 1.0.18 以降、1.2.3 以降

  • oak-run.jar バージョン 1.7.4 以降

  • インデックス作成AEMインスタンスからアクセス可能な抽出されたテキストを保存するファイルシステムフォルダー/共有

    • テキスト事前抽出の OSGi 設定には、AEM インスタンスから直接それらのファイルにアクセスできるように、抽出されたテキストファイルへのファイルシステムパスが必要です(ローカルドライブまたはファイル共有マウント)。

テキスト事前抽出を実行する方法

メモ

以下で概説する oak-run.jar コマンドを列挙した完全なリストは、https://jackrabbit.apache.org/oak/docs/query/pre-extract-text.html を参照してください。

上の図と後述の手順は、Apache Oak のドキュメントに記載されているテキスト事前抽出の技術的な手順を解説および補足しています。

テキスト事前抽出のプロセスフロー

事前抽出する内容のリストの生成

この操作中にノードストアがトラバースされるので、メンテナンス期間や低使用期間中にステップ 1(a~b) を実行します。これにより、システムに大きな負荷がかかる場合があります。

1a. 実行 oak-run.jar --generate をクリックして、事前に抽出されたテキストを持つノードのリストを作成します。

1b. ノードのリスト(1a)が CSV ファイルとしてファイルシステムに格納されます。

ノードストア全体が(oak-run コマンドのパスで指定されたとおりに)毎回トラバースされます。 --generate が実行され、 新規 CSV ファイルが作成されました。 CSV ファイルは not テキストの事前抽出プロセスを個別に実行する間に再利用されます(手順 1 ~ 2)。

ファイルシステムへのテキストの事前抽出

手順 2(a ~ c)は、AEM の通常の操作中に実行できます。この手順では、データストアのみとやり取りがおこなわれます。

2a. 実行 oak-run.jar --tika (1b) で生成された CSV ファイルに列挙されたバイナリノードのテキストを事前に抽出する

2b. (2a)で開始されたプロセスが、CSV で定義されているバイナリノードにデータストアで直接アクセスし、テキストを抽出します。

2c.抽出されたテキストは、Oak のインデックス再作成プロセス (3a) で取り込み可能な形式でファイルシステムに保存されます。

事前抽出されたテキストは、CSV 内でバイナリのフィンガープリントによって識別されます。バイナリファイルが同じである場合、事前抽出された同じテキストを AEM インスタンス間で使用できます。AEM Publish は通常AEM Author のサブセットなので、AEM Author の事前に抽出されたテキストは、AEM Publish のインデックス再作成にもよく使用できます (AEM Publish が抽出されたテキストファイルへのファイルシステムアクセス権を持っている場合 )。

事前抽出されたテキストは、時間が経つにつれて増分的に追加されることがあります。テキストの事前抽出では、以前に抽出したバイナリの抽出がスキップされるので、後でインデックス再作成が必要になる場合(抽出したコンテンツが大きくないと仮定)に備えて事前抽出済みのテキストを保持することをお勧めします。 過度に大きい場合は、テキストが十分に圧縮される zip 形式で内容を暫定的に圧縮することを検討してください)。

Oak インデックスの再インデックス、抽出されたテキストファイルからフルテキストを取得

この操作中にノードストアがトラバースされるので、メンテナンス中や低使用時にインデックス再作成(手順 3a~b)を実行します。これにより、システムに大きな負荷がかかる場合があります。

3a. 再インデックス AEMで Lucene インデックスが呼び出されます。

3b. Apache Jackrabbit Oak DataStore PreExtractedTextProvider の OSGi 設定(抽出されたテキストをファイルシステムパスで指定します)では、Oak は、抽出されたファイルからフルテキストを取得するよう指示されており、リポジトリに格納されているデータに Oak が直接アクセスして処理することを回避します。

このページ