ネストされたドキュメントをインデックスする際のパフォーマンス上の考慮事項:SolrV9.6.1 | KandaSearch Community Support Forum

ネストされたドキュメントをインデックスする際のパフォーマンス上の考慮事項:SolrV9.6.1

トピック作成者:ks-solruserml-bot (2025/04/30 11:46 投稿)
8
OpenOpen

(The bot translated the original post https://lists.apache.org/thread/o5b00j6knwxq90w48sn0gvx433jrp09z into Japanese and reposted it under Apache License 2.0. The copyright of posted content is held by the original poster.)

こんにちは、皆さん

現在、ネストされたドキュメントのインデックス化に関するPoC(概念実証)を行っており、クエリ実行時のグルーピング処理の負荷を減らすことを期待しています。

本番環境でのインデックス作成では、従来のアプローチを使用しており、どのフィールドでも変更があった場合には、ドキュメント全体を再インデックスしています(参考までに、1日に約2千万(~2cr)件のドキュメントを再インデックスしています)。
Solrのバージョン:v9.6.1

しかし、Solrのドキュメントで次のような注意点を見つけました:
DOC%20and%20supporting%20documentation%20(*)

Solrは、ネストされたドキュメントツリーに更新があった場合、内部的にそのツリー全体を再インデックスする必要がある。

つまり、ルートもしくは親ドキュメントが1000件の子ドキュメントを持っていた場合、どれか1件の子ドキュメントのフィールドが変更されただけでも、すべてのネストされた子ドキュメントが再インデックスされるということになります。これは、十分とは言えない状況です。

このことから、ネストされたドキュメントを本番環境で使用した場合に、本当にパフォーマンス向上が見込めるのか、再検討することになりました。

もしこの問題が事実であれば、本番環境でのパフォーマンス向上に役立つような、他の解決策があれば教えてください。

※補足:
外部ファイルフィールドやインプレースアップデートに関してはすでにPoCを行っており、私たちのプロジェクトでは効果がないと判断しています。

よろしくお願いいたします。
Uday Kumar

返信投稿者:ks-solruserml-bot (2025/04/30 11:46 投稿)

1つの子ドキュメントを変更すると、ブロック全体が丸ごと書き換えられます。
ただし、子ドキュメントの docValues をインプレースで更新することは、理論上は有望です(ただし、実際にどのように動作するかは分かりません)。

--
よろしくお願いします、
Mikhail Khludnev

返信投稿者:ks-solruserml-bot (2025/04/30 11:47 投稿)

これは、私たちのようなインデックス作成レートの場合、本番環境でネストされたインデックスを使用してもパフォーマンスに効果がないという意味でしょうか?

私たちはインプレースアップデートについてもPoCを行いましたが、当プロジェクトに関しては効果がないと判断したため、これとの併用も行わない予定です。

Uday Kumar

返信投稿者:ks-solruserml-bot (2025/04/30 11:47 投稿)

あなたの抱えている問題は何ですか?
解決策について尋ねるよりも、まずは問題から話し始めたほうが通常は良いです。

グルーピングについて話していましたが、フィールドの折りたたみ(field collapsing)は検討しましたか?

私の経験から言うと、ネストされたドキュメントを使うことで、インデックス時・クエリ時の両方で発生するパフォーマンスや機能面の負荷に見合うメリットが得られることは、めったにありません。

ですが、時にはそれが必要になることもあります。

また、インプレースアップデートは非常に限られた条件下でのみ機能しますが、そもそもその影響を期待する前に、あなたのユースケースがその条件を満たしているかどうか確認しましたか?

それでは!

返信投稿者:ks-solruserml-bot (2025/04/30 11:47 投稿)

また、インプレースアップデートは非常に特定の条件下でのみ発生しますが、
その影響を期待する前に、ご自身のユースケースがその条件を満たしているか確認しましたか?

―― はい、それらの仕様は考慮済みです。
ここで私たちが言いたかったのは、「インプレースアップデート自体に効果がない」という意味ではなく、
私たちのプロジェクトやスキーマにおいては効果がなかったということです。

Uday Kumar

返信投稿者:ks-solruserml-bot (2025/04/30 11:48 投稿)

こんにちは、
より良い提案をいただくために、追加の背景情報を共有させていただきます。

◆ 私たちの目的:
インデックス処理の最適化、またはSolrの応答時間の改善により、検索システムを向上させること。

◆ 現在のインデックス処理のアプローチ:
ドキュメントの1つのフィールドに変更があった場合でも、ドキュメント全体を再インデックスしています。
(1日に約2千万件(~2cr)のドキュメントを再インデックス)
Solrバージョン:V9.6.1

◆ インデックス処理の最適化に向けた取り組み:

  1. 外部ファイルフィールドに関するPOC:
    変更頻度の高いフィールドを外部ファイルに保存し、各コミット後に読み込むことで、Solrにその都度インデックスせずに済む方法です。
    参考URL

観察結果:
a. 数値フィールドにしか対応していない
b. コミュニティからも「古い機能なので使わない方が良い」との意見があり、採用を見送りました

  1. インプレースアップデートのPOC:
    変更のあったフィールドのみをインデックスし、ドキュメント全体を再インデックスしない手法です
    参考URL

観察結果:
a. 単一値フィールドのみに対応
b. インデックス最適化という点では有望だが、当プロジェクトのスキーマ(多くのマルチバリューフィールドを含む)には適していないため、こちらも見送りました

その後、Solrの応答時間の最適化に向けて、以下の手法を検討しました:

◆ ネストドキュメントに関するPOC:
参考URL

以下の文をもとに検討を始めました:
パフォーマンスの観点では、ドキュメント間の関係性をインデックス時に記録しておくことで、クエリ時に結合(join)処理を行うよりも高速になる場合が多い。

しかし、この方法では、1つの子ドキュメントに変更があるだけで、ブロック全体(親+全ての子)が再インデックスされることが判明しました。

そこでお聞きしたいこと:

  1. この「ブロック全体の再インデックス」は、従来のドキュメント再インデックスと比べて、どれほど負荷が大きいのでしょうか?
     (私たちは1日に約2千万件の再インデックスが発生しています)

  2. ネストドキュメント機能を使った場合、パフォーマンス面でどのようなトレードオフ(インデックス処理 vs クエリ処理)を期待すべきでしょうか?

  3. もしネストドキュメントが最適解でない場合、他に検討できる選択肢はありますか?

よろしくお願いいたします。
Uday Kumar

返信投稿者:ks-solruserml-bot (2025/04/30 11:48 投稿)

こんにちは、Udayさん

あなたのメールは、まさに XY問題 の典型例です。

インデックス時やクエリ実行時のことについても、試みた解決策ではなく、直面している問題やユースケースそのものを説明する必要があります。

そうすれば、こちらから具体的な提案をすることができます。

返信投稿者:ks-solruserml-bot (2025/04/30 11:49 投稿)

こんにちは、
以下に詳細を記載します:


◆ 概要:
私たちのインデックスには、サプライヤーとその製品のデータが含まれており、検索リクエストに応じてフロントエンドに表示しています。


◆ 例:サプライヤーIDが 678 の場合、インデックス内に2つの製品があります

  • product-id(ユニーク)
  • ドキュメント1:
{
  product-id: 123,
  product-price: 2000rs,
  product-name: "Jute bags",
  supplier-id: 678,
  company-name: "BagFactoryLimited"
}
  • ドキュメント2:
{
  product-id: 863,
  product-price: 4500rs,
  product-name: "Trolley bags",
  supplier-id: 678,
  company-name: "BagFactoryLimited"
}

このように、各ドキュメントには以下の情報が含まれています:

  • 製品の詳細(product-id, product-price, product-name)
  • サプライヤーの詳細(supplier-id, company-name)

◆ 問題1:(インデックス処理時)
サプライヤーの情報(例:company-name)に変更があると、そのサプライヤーに紐づくすべての製品ドキュメントを再インデックスしています。
しかしながら、サプライヤー情報は全ての製品に共通です。

FYI:
1日に約 5億件(~5Cr)のドキュメント を再インデックスしています。

冗長なデータのインデックスを避けるための、より良い最適化方法があれば教えていただきたいです。


◆ 問題2:(クエリ時)
現在のインデックスに対して検索を実行する際、各サプライヤーから最も関連性の高い製品を1件だけ 表示しています。
(たとえ1社のサプライヤーに複数の製品がヒットした場合でも)

そのために、collapseクエリ(ドキュメント間の関係性が分からないため)を使用していますが、これはリソース負荷が高いです。

例:

fq={!collapse field=supplier-id}

FYI:
1日に約 250万件(~25 Lakh)のクエリ を処理しています。

このような負荷の高いクエリを避けるための、より良いインデックス構造の設計方法があればご提案いただきたいです。


◆ Solr インフラ構成(参考):

  • バージョン: v9.6.1
  • ノード数: 8
  • シャード数: 62
  • ノードあたりのヒープメモリ: 12GB
  • ノードあたりのRAM: 50GB
  • ノードあたりのCPUコア数: 16
  • ドキュメント数: 約20億件(~20Cr)
  • インデックスサイズ: 約250GB
  • ルーティング: implicit

その他に必要な情報があれば、お知らせください。

よろしくお願いいたします。
Uday Kumar

返信投稿者:ks-solruserml-bot (2025/04/30 11:49 投稿)

もしcollapseクエリのパフォーマンスを改善したいのであれば、文字列ではなく数値型のサプライヤーIDを使ってcollapseするのが良いかもしれません。

あなたはデータを正規化せず(=非正規化)に構成していますが、これは一般的には正しいトレードオフです。ただしご自身も気づいている通り、関連するエンティティ(例:サプライヤー)が変更されたときに、多くのデータを再インデックスしなければならないという欠点があります。

in-place update の制限的な対応状況は、Lucene や Solr が改善すべき領域のひとつです。十分なリソースがある検索チームであれば、そこに投資する価値もあるでしょう。Lucene の内部構造に詳しければ、実現はそれほど遠い話ではありません。

Lucene は BinaryDocValues への更新をサポートしていますが、Solr はそれをまだ公開していません。もし公開されれば、任意のデータを好きな形式でエンコードして格納できるでしょう。ただし、BinaryDocValues は「取得」以外の用途(ソート、ファセット、関連度、フィルタリング)にはほぼ使えないため、あまり実用的ではないかもしれません。

おそらく、supplier(サプライヤー)ごとにシャーディングしているのではないでしょうか?(つまり、各サプライヤーのデータは特定のシャード内に収まっている)
なぜなら、collapseをsupplier-idでかけているようなので。


~ David

トピックへ返信するには、ログインが必要です。

KandaSearch

Copyright © 2006-2025 RONDHUIT Co, Ltd. All Rights Reserved.

投稿の削除

この投稿を削除します。よろしいですか?