はじめに
イントラネットの検索エンジンを作っていて、Solr8(8.11.2)がそろそろ終りになるのでSolr9(9.6.1)にアップグレードすることにしました。
KubernetesでSolrCloudを運用しているので単純にコンテナのバージョンをdocker.io/library/solr:9.6.1にしたのですが、だいたい動作するもののhighlightingの結果が空になってしまいました。
さらに面倒なことに、検索文字列やオプションの指定によって空にならない場合もあるため原因の調査に少し時間がかかりました。
タイトルではrequireFieldMatchをtrueにしなければいけないといった印象を与えますが、これは自分の環境においてはという事です。問題が発生していなければfalseの方が使い勝手が良い環境もあると思います。
調査
まず自作のWebアプリは検索結果をJSONでも出力できるので、現在のQueryパラメータがどんなものか確認していきます。
{
"responseHeader": {
"zkConnected": true,
"status": 0,
"QTime": 85,
"params": {
"hl": "on",
"fl": "id,title,author,copyright,parent_url,last_update",
"hl.fragsize": "200",
"start": "0",
"fq": "last_update:[2024-03-28T11:21:02Z TO NOW]",
"sort": "last_modified desc",
"rows": "10",
"hl.simple.pre": "<em class=\"matched-querystring\">",
"usePhraseHighLighter": "true",
"q": " ( content:空調申請 ) AND id:*example.org/official/*",
"defType": "edismax",
"hl.simple.post": "</em>",
"qf": "content^100",
"hl.fl": "content",
"wt": "json"
}
},
...
"highlighting": {
"https://intra.example.org/hoge.pdf": {},
...
}
}
usePhraseHighLighterは必要ない気もしますが、とりあえずこれでいままで返されていた"highlighting"フィールドの出力が空になっていることが分かります。
問題は検索文字列によっては、ちゃんとhighlightingが返ってくる点です。
またバージョンアップ以前のSolr8の時に保存したドキュメントでも、新しくSolr9後に更新したドキュメントでもhighlightingが返ってきたり、空になったりしているので、機能そのものが動いていないということではないようです。
Solr管理コンソールからの原因追及
続いて管理系ネットワークからSolrのAdminコンソールに接続して、いろいろパラメータを調整してみます。
hl関連のパラメータは多くないので、"hl.requireFieldMatch" をチェックするとhighlightingに意味のある結果が返ってくるようになりました。
また"hl.highlightMultiTerm"の値が影響しない場合もありましたが、trueの方が全体としては期待したどおりの挙動になるようでした。
対応
Ruby/Sinatraで開発しているWebアプリケーションのコードに :"hl.requireFieldMatch" => "true",
を追加することで対応しました。
Solr管理コンソールで"highlightMultiTerm"の状態によっても結果が変化しましたが、このデフォルト値は"true"なのでコードを変更することはしませんでした。
結果的にアプリケーションは期待したように動作していて、無事に問題は解決してSolr8からSolr9へのアップグレード対応も完了しました。
さいごに
Solrは非常に強力な全文検索エンジンで、それほどチューニングに時間を割かなくても概ね期待したような動作をしてくれます。
ただUTF-8を当然のように要求してくるので、内部のドキュメントを保存するためにPostScriptファイルをPDFに変換したり、EUCやShift-JISのコードをUTF-8に変換するような仕組みを入れる日本語対応の部分では対応が必要になってきます。
requireFieldMatch について
このデフォルト値はfalseです。ちなみにusePhraseHighLighterのデフォルト値はtrueなので、動作には影響ありませんでした。
これがfalseであれば、より広い対象が対象となるため合理的な初期値ではあると思います。
根本原因は分かっていませんが、他にもcontent_ngramのような似たような名前のフィールド定義があった事も影響していたかもしれません。
Highlighting周りの挙動はSolr9になってから少し変化したのかもしれません。
バージョンアップとは関係なく、highlightingが空になる場合
そもそものfield定義で、"stored"を"true"に設定する必要があります。そのため"hl.fl"に設定する対象のfieldのschemaを確認しておくことも必要です。
QueryはちゃんとしているのにHighlighting機能そのものが動作しないように思われる場合は、Solr Adminからschemaを確認して、"Stored"のチェックを確認しましょう。
以上