OpenSearch アップグレード ガイド

Confluence 8.7 への準備

このページの内容

お困りですか?

アトラシアン コミュニティをご利用ください。

コミュニティに質問

変更内容

Confluence 9.0 で、OpenSearch はオプトイン機能になりました。アプリ開発者として Lucene API を単独で使用している場合は、OpenSearch エンジンの機能を利用する顧客のサービス中断を最小限に抑えるために、Confluence 検索 v2 API への移行を検討してください。検索 API v2 との互換性は、できる限り維持される予定です。そのため、現在の統合の大半において問題は発生しません。

OpenSearch でプラグインをテストする

プラグインをテストして、OpenSearch で想定どおりに動作することを確認してください。開始するには、「Confluence による OpenSearch の設定」ガイドを参照してください。

廃止と変更

インデックス フィールドはドキュメント間で一貫する必要があります

アトラシアンは、FieldDescriptor を使用して、通常 Extractor2 からインデックス化されたドキュメントに対してフィールドとして値 (filename など) を追加します。各 FieldDescriptor は、フィールドのインデックス化とクエリの方法を説明するマッピングに関連付けられています。たとえば、フィールドのインデックス化とクエリには、そのタイプ (string vs text vs long) とアナライザーが使用されることがあります。

以前は、同じインデックス内のドキュメント間で、異なるマッピングを持つ特定のフィールド名を追加できました。たとえば、あるドキュメントには filenametext として追加し、別のドキュメントには string として追加することが可能でした。

変更内容: ロールアウト後は、フィールド マッピングを混在させると、ログ ファイルにエラー メッセージが表示されるようになります。なお、エラー メッセージは次のように表示されます。

Mapping for 'filename' (TextFieldMapping {name='filename'}) conflicts with existing mapping (StringFieldMapping {name='filename'})

このエラー メッセージは、現時点では Lucene に悪影響を及ぼしません。しかし、OpenSearch では問題を引き起こします。このマッピングの競合は、フィールドのインデックスが正しく行われないか、ドキュメント全体がインデックス化されない可能性があることを意味します。

時期: Confluence 8.8

最新情報: このエラーを修正するには、インデックスのすべてのドキュメントでフィールドが同じマッピングを使用するか、別の名前を使用する必要があります(例: filename.textfilename.string)。

コード内でこれを効果的に適用するには、FieldMapping でフィールドを明示的に記述することをお勧めします。 たとえば、この非推奨コードの代わりに、次のように記述します。

// Constant public static final String FILENAME = "filename"; // Extractor A fields.add(new TextFieldDescription(FILENAME, docA.getName(), Stored.YES, new FilenameAnalyzerDescriptor())); // Extractor B fields.add(new TextFieldDescription(FILENAME, docB.getName(), Stored.YES, new FilenameAnalyzerDescriptor()));

代わりに、次のようにコードを記述します。

// Constant public class MyFields implements FieldMappingsProvider { public static final TextFieldMapping FILENAME = TextFieldMapping.builder("filename") .store(true) .analyzer(new FilenameAnalyzerDescriptor()) .build(); @Override public Collection<FieldMapping> getFieldMappings() { return List.of(FILENAME); } } // Extractor A fields.add(MyFields.FILENAME.createField(docA.getName())); // Extractor B fields.add(MyFields.FILENAME.createField(docB.getName()));

atlassian-plugin.xmlFieldMappingsProvider にマッピングを明示的に登録して、プラグインの起動時に OpenSearch インデックスにマッピングが作成されるようにするのがベストプラクティスです。あるいは、それらのマッピングを使用してドキュメントをインデックス化すると、Confluence はそれらを動的に作成します。

<field-mappings-provider key="my-custom-fields" index="CONTENT" class="com.example.MyFields" />

AnalyzerDescriptor が廃止されました

以前は、TokenizerDescriptorCharFilterDescriptorTokenFilterDescriptor の任意の組み合わせを指定することで、AnalyzerDescriptor によって特注のアナライザーを構築できました。これを行うことで、アナライザーがインデックス化(例: TextFieldDescriptor)やクエリ(例: PhraseQuery)に使用できました。

変更内容: AnalyzerDescriptor で定義された特注のアナライザーは廃止され、OpenSearch で動作しなくなります。

時期: Confluence 8.7

最新情報: OpenSearch では、Confluenceが提供する定義済みのアナライザーのみを使用できます(つまり AnalyzerDescriptor ではありません)。

Confluence でサポートされている定義済みアナライザーの最新のリストは、MappingAnalyzerDescriptor の「現在実装されているすべてのクラス」セクションでご確認ください。

contentBody フィールドは保存されません

Confluence コンテンツ インデックスでは、contentBody フィールドにドキュメントのインデックス化されたコンテンツが格納されるため、クエリを実行できます。

これまでは、このフィールドは保存されており、元の値を取得するために使用できました。たとえば、検索スキャン方法の requestedField パラメーターに含めることが可能でした。

変更内容: contentBody が保存フィールドではなくなりました。

時期: Confluence 8.7

最新情報: 代わりに、ドキュメントのコンテンツの元の値が、contentBody-stored という新しい別のフィールドに保存されます。現在、contentBody フィールドでドキュメント コンテンツを取得している場合は、代わりに contentBody-stored をご利用ください。なお、contentBody フィールドは引き続きインデックス化され、クエリ(例: CQL contentBody:foo を介したクエリ)に使用されます。

SearchIndex が廃止され、Index に置き換えられました

SearchIndexCONTENTCHANGE などのシステム インデックスにのみ役立つ列挙型です。以前までは、独自のカスタム インデックスを管理するためにプラグインでインデックス名を使用する必要がありました。また、検索プラットフォームが OpenSearch の場合は、リクエストが作成されるたびに列挙値を OpenSearch に保存されているインデックスの実名に変換する必要があったため、手間がかかかっていました

変更内容: SearchIndex が廃止され、Index に置き換えられました。

時期: Confluence 8.7

新機能: インデックスをシステム インデックスとカスタム インデックスの両方に使用できます。この新しいクラスを使用すると、次のようないくつかの利点があります。

  • システム インデックスとカスタム インデックスのどちらでも、検索プラットフォームが Lucene か OpenSearch かにかかわらず、インデックスの操作方法が統一されます。

  • インデックス名の抽象化により、コードがより簡潔になり、保守が容易になります。

並べ替えの変更と更新

TextFieldMapping

Lucene では、テキスト フィールド(つまり TextFieldMapping)で並べ替えリクエストが許可されていました。しかし、これらのリクエストには問題がありました。フィールドはトークン化されていてテキストが多く、結果が不正確で非効率的になる可能性があったからです。代わりに、キーワード フィールドで検索することをお勧めします(つまり StringFieldMapping)。

変更内容: OpenSearch ではテキスト フィールドでのソートができないため、このような操作では次のエラーが発生します。

Text fields are not optimised for operations that require per-document field data like aggregations and sorting, so these operations are disabled by default. Please use a keyword field instead.

時期: Confluence 8.9

新着情報: 回避策は、テキスト フィールドをキーワード、つまり StringFieldMapping として作成することです。

UserAttributeSort

以前まで、Lucene ではユーザー属性による並べ替えリクエストが許可されていました (UserAttributeSort によって作成)。並べ替える前に検索クエリで見つかったドキュメントごとにユーザーの詳細を個別に取得する必要があったため、このリクエストではリソースを大量に消費することがありました。

変更内容: クラス UserAttributeSort は廃止され、OpenSearch ではサポートされていません。

時期: Confluence 8.9

新着情報: 現段階では回避策はありません。

LowercaseFieldSort

クラス LowercaseFieldSort を使用すると、キーワード フィールドの小文字値に基づいてソートできます

変更内容: OpenSearch は小文字ソートをネイティブにサポートしていません。そのため、LowercaseFieldSort を効率的に実装するために、クラス StringFieldMappingLowercaseFieldSort に変更が加えられました。

時期: Confluence 8.9

新機能:

StringFieldMapping

StringFieldMapping に、OpenSearch のみに関連する 2 つの新しいプロパティを導入しました。これらの変更は、Confluence が OpenSearch を使用するように設定されている場合にのみ有効になることに注意してください。

  • asLowercase が true の場合:

    • インデックス フェーズ: 影響はありません。

    • 検索フェーズ: この設定は、フィールドがすでに小文字で保存されていることを示しているため、Confluence はそのフィールドをそのまま使用して結果をソートします。

  • withLowercase が true の場合:

    • インデックス フェーズ: 元のフィールドの小文字バージョンを保存するサブフィールドが作成されます。

    • 検索フェーズ: 元のフィールドの代わりにサブフィールドがソートに使用されます。

LowercaseFieldSort

LowercaseFieldSort クラスに、ソート順序に加えて、フィールド名だけでなく StringFieldMapping 引数を取る新しいコンストラクターを導入しました。この引数は、小文字値の保存方法に基づいて、フィールドにおける OpenSearch での小文字ソートの処理方法を、Confluence に指示します。

下位互換性を保つため、Confluence は次のようなシナリオでは OpenSearch のスクリプト ソート版を使用するようにフォールバックします。

  • LowercaseFieldSortStringFieldMapping では構成されていません。

  • LowercaseFieldSortStringFieldMapping で構成されていますが、フィールド マッピングでは asLowercasewithLowercase の両方が false です。

このフォールバックはパフォーマンスに悪影響を与えるため、次のソートを使用して既存のコードを更新し、LowercaseFieldSort を適切な StringFieldMapping で構成することをお勧めします。

検出を目的、このフォールバックが使用されるたびに Confluence は次の警告ログを出力します。

Using script sort for field: {field_name}. This will significantly impact query performance. Please consider migrating the field to support lowercase sub field for better performance

結果ウィンドウの上限

ISearch オブジェクトに limitoffset を定義することで、検索ウィンドウをページ分割できます。これらの数値 (limit + offset) が大きいほど、検索エンジンが移動する必要のあるインデックス ドキュメントが多くなります。これは「結果ウィンドウ」と呼ばれ、メモリ使用量に比例します。たとえば、検索の 1000 ページ目 (1 ページあたり 20 件の結果) を返すには、最初のページを返すよりもはるかに多くのリソースが必要です。

Lucene では、現在、この結果ウィンドウに制限はありません。

変更内容: 既定では、OpenSearch の結果ウィンドウには 10,000 件という制限、つまり、検索でリクエストできる結果の量が定められています。この制限を超えるリクエストは拒否され、次のようなエラーが表示されます。

Result window is too large, from + size must be less than or equal to: [10000] but was [10010]. See the scroll api for a more efficient way to request large data sets. This limit can be set by changing the [index.max_result_window] index level setting.

時期: Confluence 8.9

最新情報: 検索クエリを OpenSearch で機能させるには、制限として小さな数字を渡す必要があります。また、ユーザーが移動できるページ数を制限する必要もあります。つまり、オフセットを小さくする必要があります。

大量のデータを繰り返し処理する必要がある場合は、SearchManager.scan メソッドの使用を検討してください。

また、検索がフィールド(例: modified_id など)でソートされている場合、OpenSearch では、SearchAfter を(offset の代わりに)使用して検索を効率的にページ分割する方法も用意しています。これは結果ウィンドウの制限の影響を受けません。ただし、このパラメーターは Lucene ではサポートされていません。

OpenSearch のドキュメンテーションで search_after を調べてください

検索結果の次のページのトークンに対する変更

以前は、検索 (SearchManager.search) を実行すると、返される SearchResults オブジェクトには getNextPageSearch というメソッドがあり、これを使用して検索の次のページ (存在する場合) を取得できました。getNextPageSearch プロパティは常にトークンとともに返されたため、以降の検索は最初の検索で使用されたものと同じバージョンのインデックスに対して実行できました。これにより、連続するページ分割検索の一貫性が確保され、特に大量のドキュメントを繰り返し処理する場合に便利です (たとえば、バッチ処理の一部として)。

トークンを生成するとリソースが消費されるため、必要な場合だけでなく、検索のたびに実行すると無駄になります。

時期: Confluence 9.0

変更内容: OpenSearch では getNextPageSearchトークンとともに返されなくなります。既存のプラグインを壊さないように、Lucene ではまだ返されますが、これは将来変更される可能性があります。次のページの検索でトークンを取得するには、SearchManager.search で最初の検索を実行するときに ISearch.generatesToken() を true (既定値は false) に設定します。

ページ分割検索でのデータの一貫性を維持するためにコードがこのバージョン トークンに依存している場合は、ISearch.generatesToken() を true に設定してください。

ヒント

カスタム インデックスの再構築

プラグインがカスタム インデックスを管理している場合は、ReIndexRequestEvent のリスナーを作成することをお勧めします。このリスナーはカスタム インデックスを再構築します。これにより、管理者が(コンテンツのインデックス作成管理者ページから)インデックスの再構築を要求したときに、プラグイン内のカスタム インデックスを含むすべてのインデックスが再構築されます。

最終更新日 2024 年 7 月 2 日

この内容はお役に立ちましたか?

はい
いいえ
この記事についてのフィードバックを送信する
Powered by Confluence and Scroll Viewport.