search-ann-benchmarkにElasticsearch 9.2のDiskBBQを追加

ベクトル検索エンジンの性能評価ツールsearch-ann-benchmarkで、Elasticsearch 9.2で追加されたDiskBBQ(bbq_disk)インデックスタイプの評価を追加しました。

DiskBBQとは

DiskBBQは、Elasticsearch 9.2で導入された新しいベクトルインデックスタイプです。従来のBBQ(Better Binary Quantization)がメモリベースのHNSWグラフを使用するのに対し、DiskBBQはディスクベースで動作します。

これにより、メモリ使用量を抑えつつ大規模なベクトルデータを扱えるようになります。ただし、ディスクアクセスが発生するため、検索速度とのトレードオフがあります。

search-ann-benchmarkの変更内容

主な変更点は以下の3つです。

CLIオプションの追加

--quantizationオプションにbbq_diskを追加しました。これで、コマンドラインからDiskBBQを使用したベンチマークを実行できます。

search-ann-benchmark run elasticsearch \
  --target 100k-768-m32-efc200-ef100-ip \
  --version 9.2.3 \
  --quantization bbq_disk

インデックス作成ロジックの調整

DiskBBQは従来のHNSWパラメータ(mef_construction)をサポートしないため、インデックス作成時にこれらのパラメータを除外するように修正しました。

GitHub Actionsワークフローの追加

DiskBBQ専用のベンチマークワークフローを追加しました。Elasticsearch 9.2.3を使用して、100k、1M、5Mのデータセットに対してテストできます。

大規模データセットでの効果

DiskBBQは、メモリ使用量の削減が主な目的のため、小規模なデータセットでは従来のbbq_hnswとの差があまり出ないかもしれません。5M以上のベクトルを扱うような大規模なデータセットで、メモリ効率の違いがより明確になると思います。

    fess-ds-microsoft365プラグインの権限設定について

    FessでMicrosoft 365のコンテンツをクロールするためのプラグイン「fess-ds-microsoft365」を利用する際、Entra IDでどのMicrosoft Graph API権限を設定すればよいかを詳しく解説します。DataStoreごとに必要な権限が異なるため、使用する機能に応じて最小限の権限を設定することをお勧めします。

    権限一覧(クイックリファレンス)

    まず、各DataStoreで必要な権限を一覧で示します。

    DataStore必須権限条件付き権限
    OneDriveDataStoreFiles.Read.AllUser.Read.All, Group.Read.All, Sites.Read.All
    OneNoteDataStoreNotes.Read.AllUser.Read.All, Group.Read.All, Sites.Read.All
    TeamsDataStoreTeam.ReadBasic.All, Group.Read.All, Channel.ReadBasic.All, ChannelMessage.Read.All, ChannelMember.Read.All, User.Read.AllChat.Read.All, Files.Read.All
    SharePointDocLibDataStoreFiles.Read.All, Sites.Read.All
    SharePointListDataStoreSites.Read.All
    SharePointPageDataStoreSites.Read.All

    SharePoint系のDataStoreでは、site_idを指定する場合、Sites.Read.Allの代わりにSites.Selectedを使用できます。

    OneDriveDataStore

    ユーザー、グループ、SharePointサイトのOneDriveファイルをクロールします。

    必要な権限

    権限必須/条件付き条件
    Files.Read.All必須ドライブとファイルへのアクセスに必要
    User.Read.All条件付きuser_drive_crawler=trueの場合(デフォルト: true)
    Group.Read.All条件付きgroup_drive_crawler=trueの場合(デフォルト: true)
    Sites.Read.All条件付きshared_documents_drive_crawler=trueの場合(デフォルト: true)

    使用されるGraph APIエンドポイント

    エンドポイント用途条件
    GET /usersライセンス付きユーザーの取得user_drive_crawler=true
    GET /groupsMicrosoft 365グループの取得group_drive_crawler=true
    GET /users/{id}/driveユーザーのドライブを取得user_drive_crawler=true
    GET /groups/{id}/driveグループのドライブを取得group_drive_crawler=true
    GET /sitesすべてのサイトを取得shared_documents_drive_crawler=true
    GET /sites/{id}/sites子サイトを取得(再帰的)shared_documents_drive_crawler=true
    GET /sites/{id}/drivesサイトのドライブを取得shared_documents_drive_crawler=true
    GET /drives/{id}/items/{id}/childrenドライブアイテムの一覧常時
    GET /drives/{id}/items/{id}/contentファイルコンテンツの取得常時
    GET /drives/{id}/items/{id}/permissionsアイテムの権限を取得常時

    最小権限の設定

    ユーザーのOneDriveのみをクロールする場合:

    Files.Read.All, User.Read.All

    グループ共有ドキュメントとSharePoint共有ドキュメントが不要な場合は、パラメータを以下のように設定します:

    user_drive_crawler=true
    group_drive_crawler=false
    shared_documents_drive_crawler=false

    OneNoteDataStore

    OneNoteのノートブック、セクション、ページをクロールします。

    必要な権限

    権限必須/条件付き条件
    Notes.Read.All必須OneNoteコンテンツへのアクセスに必要
    User.Read.All条件付きuser_note_crawler=trueの場合(デフォルト: true)
    Group.Read.All条件付きgroup_note_crawler=trueの場合(デフォルト: true)
    Sites.Read.All条件付きsite_note_crawler=trueの場合(デフォルト: true)

    使用されるGraph APIエンドポイント

    エンドポイント用途条件
    GET /usersライセンス付きユーザーの取得user_note_crawler=true
    GET /groupsMicrosoft 365グループの取得group_note_crawler=true
    GET /sites/rootルートサイトの取得site_note_crawler=true
    GET /users/{id}/onenote/notebooksユーザーのノートブックを取得user_note_crawler=true
    GET /groups/{id}/onenote/notebooksグループのノートブックを取得group_note_crawler=true
    GET /sites/{id}/onenote/notebooksサイトのノートブックを取得site_note_crawler=true
    GET /onenote/notebooks/{id}/sectionsノートブックのセクションを取得常時
    GET /onenote/sections/{id}/pagesセクションのページを取得常時
    GET /onenote/pages/{id}/contentページのコンテンツを取得常時

    TeamsDataStore

    Teamsのチャンネル、メッセージ、チャットをクロールします。Teamsは他のDataStoreと比べて必要な権限が多くなります。

    必要な権限

    権限必須/条件付き条件
    Team.ReadBasic.All必須チーム情報へのアクセスに必要
    Group.Read.All必須TeamsはMicrosoft 365グループに基づく
    Channel.ReadBasic.All必須チャンネル情報へのアクセスに必要
    ChannelMessage.Read.All必須チャンネルメッセージの読み取りに必要
    ChannelMember.Read.All必須チャンネルメンバー情報(権限用)に必要
    User.Read.All必須ユーザータイプの解決に必要
    Chat.Read.All条件付きchat_idを指定している場合
    Files.Read.All条件付きappend_attachment=trueの場合

    使用されるGraph APIエンドポイント

    エンドポイント用途条件
    GET /teamsすべてのチームを取得team_idを指定していない場合
    GET /groups/{id}特定のチームを取得team_idを指定した場合
    GET /teams/{id}/channelsチャンネルを取得channel_idを指定していない場合
    GET /teams/{id}/channels/{id}特定のチャンネルを取得channel_idを指定した場合
    GET /teams/{id}/channels/{id}/messagesチャンネルメッセージを取得常時
    GET /teams/{id}/channels/{id}/messages/{id}/repliesリプライメッセージを取得ignore_replies=falseの場合(デフォルト)
    GET /teams/{id}/channels/{id}/membersチャンネルメンバーを取得権限用
    GET /chats/{id}/messagesチャットメッセージを取得chat_idを指定した場合
    GET /chats/{id}/membersチャットメンバーを取得chat_idを指定した場合
    GET /shares/{id}/driveItem/content添付ファイルのコンテンツを取得append_attachment=trueの場合

    注意点

    Teamsでチャンネルメッセージのみをクロールする場合(チャットは不要、添付ファイルも不要)の最小権限は以下の通りです:

    Team.ReadBasic.All, Group.Read.All, Channel.ReadBasic.All, ChannelMessage.Read.All, ChannelMember.Read.All, User.Read.All

    SharePointDocLibDataStore

    SharePointドキュメントライブラリとそのファイルをクロールします。

    必要な権限

    権限必須/条件付き条件
    Files.Read.All必須ドキュメントライブラリとファイルへのアクセスに必要
    Sites.Read.All必須site_idを指定しない場合(すべてのサイトを列挙)
    Sites.Selected必須site_idを指定した場合(Sites.Read.Allの代替)

    Files.Read.Allに加えて、Sites.Read.AllまたはSites.Selectedのいずれかが必要です。

    使用されるGraph APIエンドポイント

    エンドポイント用途条件
    GET /sitesすべてのサイトを取得site_idを指定していない場合
    GET /sites/{id}/sites子サイトを取得(再帰的)site_idを指定していない場合
    GET /sites/{id}特定のサイトを取得site_idを指定した場合
    GET /sites/{id}/drivesドキュメントライブラリを取得常時
    GET /drives/{id}/items/root/childrenドライブアイテムの一覧常時
    GET /drives/{id}/items/{id}/contentファイルコンテンツの取得常時
    GET /drives/{id}/items/root/permissionsドライブの権限を取得常時

    SharePointListDataStore

    SharePointリストとそのアイテムをクロールします。

    必要な権限

    権限必須/条件付き条件
    Sites.Read.All必須site_idを指定しない場合(すべてのサイトを列挙)
    Sites.Selected必須site_idを指定した場合(Sites.Read.Allの代替)

    使用されるGraph APIエンドポイント

    エンドポイント用途条件
    GET /sitesすべてのサイトを取得site_idを指定していない場合
    GET /sites/{id}特定のサイトを取得site_idを指定した場合
    GET /sites/{id}/listsリストを取得常時
    GET /sites/{id}/lists/{id}特定のリストを取得list_idを指定した場合
    GET /sites/{id}/lists/{id}/itemsリストアイテムを取得常時
    GET /sites/{id}/lists/{id}/items/{id}アイテムの再取得(フォールバック)フィールドが空の場合
    GET /sites/{id}/permissionsサイトの権限を取得権限用

    SharePointPageDataStore

    SharePointページ(サイトページ、ニュースページ、Wikiページなど)をクロールします。

    必要な権限

    権限必須/条件付き条件
    Sites.Read.All必須site_idを指定しない場合(すべてのサイトを列挙)
    Sites.Selected必須site_idを指定した場合(Sites.Read.Allの代替)

    使用されるGraph APIエンドポイント

    エンドポイント用途条件
    GET /sitesすべてのサイトを取得site_idを指定していない場合
    GET /sites/{id}特定のサイトを取得site_idを指定した場合
    GET /sites/{id}/pagesサイトページを取得常時
    GET /sites/{id}/pages/{id}ページのコンテンツを取得常時
    GET /sites/{id}/permissionsサイトの権限を取得権限用

    Sites.Selected権限の設定方法

    SharePoint系のDataStore(SharePointDocLib、SharePointList、SharePointPage)でsite_idを指定する場合、Sites.Read.Allの代わりにSites.Selectedを使用できます。これにより、特定のサイトにのみアクセスを限定できます。

    設定手順

    1. Azure Portalでアプリ登録にSites.Selected権限を付与
    2. Microsoft Graph PowerShellまたはAPIを使用して、特定サイトへのアクセス権を付与
    3. 各対象サイトへのアクセスを明示的に許可

    参考: https://learn.microsoft.com/en-us/graph/permissions-reference#sitesselected

    全権限一覧

    権限用途使用するDataStore
    User.Read.Allユーザー情報、ライセンス確認OneDrive, OneNote, Teams
    Group.Read.AllMicrosoft 365グループの取得OneDrive, OneNote, Teams
    Files.Read.Allファイルとドライブの読み取りOneDrive, SharePointDocLib, Teams(添付ファイル)
    Notes.Read.AllOneNoteコンテンツの読み取りOneNote
    Sites.Read.AllすべてのSharePointサイトの列挙OneDrive, OneNote, SharePointDocLib, SharePointList, SharePointPage
    Sites.Selected特定サイトのみへのアクセスSharePointDocLib, SharePointList, SharePointPage(site_id指定時)
    Team.ReadBasic.Allチームの基本情報Teams
    Channel.ReadBasic.Allチャンネルの基本情報Teams
    ChannelMessage.Read.Allチャンネルメッセージの読み取りTeams
    ChannelMember.Read.Allチャンネルメンバーの読み取りTeams
    Chat.Read.Allチャットメッセージの読み取りTeams(chat_id指定時)

    最小権限の考え方

    アプリケーションに付与する権限は、必要最小限に抑えることが推奨されます。

    1. OneDriveDataStore: 不要なクローラーを無効化
    2. user_drive_crawler=falseでUser.Read.Allを省略
    3. group_drive_crawler=falseでGroup.Read.Allを省略
    4. shared_documents_drive_crawler=falseでSites.Read.Allを省略

    5. OneNoteDataStore: OneDriveと同様のパターン

    6. user_note_crawler=falsegroup_note_crawler=falsesite_note_crawler=falseを必要に応じて設定

    7. SharePoint系DataStore: site_idを指定

    8. Sites.Read.Allの代わりにSites.Selectedを使用
    9. Azure ADでサイトごとの追加設定が必要

    10. TeamsDataStore: オプション機能をスキップ

    11. chat_idを指定しなければChat.Read.Allは不要
    12. append_attachment=falseでFiles.Read.Allは不要

    まとめ

    fess-ds-microsoft365プラグインでは、使用するDataStoreと設定パラメータによって必要な権限が異なります。本ガイドを参考に、使用する機能に応じた最小限の権限を設定してください。Entra IDの管理者に権限申請する際にも、「このDataStoreを使うからこの権限が必要」と具体的に説明できるようになります。

    Fessのクローラーで Apache HttpClient 5.x をサポート

    Fessのクローラーライブラリであるfess-crawlerに、Apache HttpComponents 5.x のサポートを追加しました。

    これまでfess-crawlerでは Apache HttpComponents 4.x を使用していましたが、5.x系ではHTTP/2のサポートやパフォーマンスの改善など、多くの機能強化が行われています。今回の対応により、fess-crawlerでも最新のHttpClientを利用できるようになりました。

    主な変更点

    新しいHTTPクライアント実装

    • Hc5HttpClient – Apache HttpComponents 5.x を使用した新しいHTTPクライアント実装
    • Hc4HttpClient – 既存の4.x系実装(後方互換性のために維持)

    デフォルトの切り替え

    Fess 15.5からは、問題がなければHttpClient 5系をデフォルトとして使用する予定です。

    後方互換性

    以前のHttpClient 4系を利用したい場合は、fess_config.propertiesのクローラーオプションに以下の設定を追加することで切り替えられます。

    jvm.crawler.options=\
    -Dfess.crawler.http.client=hc4\n\
    ...

    技術的な詳細

    今回の実装では、既存のHcHttpClientを抽象クラスとしてリファクタリングし、共通ロジックを共有する形でHc4HttpClientHc5HttpClientを実装しています。これにより、両方のバージョンを同じインターフェースで利用でき、切り替えも容易になっています。

    また、以下の機能もHttpClient 5.x向けに実装されています。

    • 認証機能(Basic、Digest、NTLM、SPNEGO)
    • フォームベース認証
    • コネクションプール監視
    • 国際化ドメイン名(IDN)対応のDNSリゾルバ

    関連リンク