LoginSignup
3
2

More than 5 years have passed since last update.

Solr の RankQuery プラグイン

Last updated at Posted at 2018-04-19

昨年参加したSolr勉強会yahooの矢野さんがお話されていた Solr の RankQuery を試してみました。Solr に実装されている ReRankQuery を試した後、フィールド値で上位N件を並び替えるプラグインを作成してみました。

はじめに

RankQuery は、元のクエリの結果に対して追加処理を加えて動作を変更する機能になります。
具体的には、元のクエリのソート結果のトップN件数だけ追加指定した条件でソートし直すといった用途に使われているようです。詳細については矢野さんが詳しい情報をQiitaで公開されているので、そちらをご参照ください。

環境構築

README.md の手順で環境構築を行います。

ReRankQuery

ReRankQuery は、Solrに標準で実装されているクエリで、元のクエリの検索結果について、reRankDocs で指定した順位までを対象に、rqq で指定した query 実行時のスコアをreRankWeightの重みで元クエリのスコアに加算したものを新たなスコアとし、その値でソートした結果に置き換えるクエリです。rqq で指定したquery にヒットしない場合、元クエリのスコアがそのまま使われます。また、加算後スコアが同じ値の場合は、内部的に持つdocIDの小さい順にソートされます。

# 擬似コード
if(match_rqq_query) {
   new_score = original_score + reRankWeight * rqq_score;
} else {
   new_score = original_score;
}

元になるクエリ

山手」を含むレコードを抽出し、weighの大きい順に取得するクエリです。

http://localhost:8983/solr/sample01/select?fl=id,payload,weight,score&q=payload:山手&wt=csv&rows=5&sort=weight desc

id payload weight score
24 東京 山手線 915 1.6172552
15 駒込 山手線 881 1.6172552
4 恵比寿 山手線 868 1.6172552
28 田町 山手線 831 1.6172552
17 西日暮里 山手線 826 1.6172552

リランククエリ1

reRankDocs=3 reRankWeight=1.0 rqq=(payload:恵比寿) のReRankQueryを実行します。

http://localhost:8983/solr/sample01/select?fl=id,payload,weight,score&q=payload:山手&wt=csv&rows=5&sort=weight desc&&rq={!rerank reRankQuery=$rqq reRankDocs=3 reRankWeight=1.0}&rqq=(payload:恵比寿)

id payload weight score 順位 元順位 元score
4 恵比寿 山手線 868 5.553081 1 3 1.6172552
15 駒込 山手線 881 1.6172552 2 2 1.6172552
24 東京 山手線 915 1.6172552 3 1 1.6172552
28 田町 山手線 831 1.6172552 4 4 1.6172552
17 西日暮里 山手線 826 1.6172552 5 5 1.6172552
  • 上位3件の順序が入れ替わっています。
    • 恵比寿を含むid=4のscoreだけ変化し、1位になっています。
    • id=15とid=24 の順序が変わっています。最終的なscoreが同じ場合、docIDの小さいほうが先になる(※)というルールが適用されています。
  • id=28,id=17は並べ替え対象外なので、docIDの小さい順になっていません。

 ※docIDとフィールドidの大小が同じになるようデータ登録しています

リランククエリ2

reRankDocs=3 reRankWeight=1.0 rqq=(payload:田町) のReRankQueryを実行します。

http://localhost:8983/solr/sample01/select?fl=id,payload,weight,score&q=payload:山手&wt=csv&rows=5&sort=weight desc&&rq={!rerank reRankQuery=$rqq reRankDocs=3 reRankWeight=1.0}&rqq=(payload:田町)

id payload weight score 順位 元順位 元score
4 恵比寿 山手線 868 1.6172552 1 3 1.6172552
15 駒込 山手線 881 1.6172552 2 2 1.6172552
24 東京 山手線 915 1.6172552 3 1 1.6172552
28 田町 山手線 831 1.6172552 4 4 1.6172552
17 西日暮里 山手線 826 1.6172552 5 5 1.6172552
  • リランククエリ1と同じ並びですが、id=4のscoreが元scoreと同じです。
  • docIDの小さい順に並ぶというルールが適用されています。

RankQuery plugin

ReRankQueryの実装である、ReRanqQparserPlugin.java を参考にして、元クエリで検索後に、フィールド値を見てスコアを再計算するプラグインを作成しました。
SampleReRankQParserPlugin.java

本来は、Weight/Scorer クラスも実装して実現するようですが、今回はそれらを実装せず直接フィールド値を見に行くという手抜き実装にっています。これにあわせて、ReRankQueryの中で使われている、QueryRrescorer.javaクラスの代わりに使う、クラスを実装しました。
SampleRescorer.java

plugin 仕様

  • rq={!sample ...} で呼び出します。
  • reRankDocs で並び替えの対象とするドキュメント数を指定します。
  • reRankModulo で指定した約数のid のスコアを最初のクエリの最大スコア + weight値で置き換えます。
  • ReRanqQuery と違い、スコア再計算の際にクエリを使えません。(rqq指定なし)
#擬似コード
if((field_id % reRankModulo) == 0) {
   new_score = max(original_scores) + field_weight;
} else {
   new_score = original_score;
}

plugin 仕様方法

パスの通った場所にコンパイル済のjarファイルを設置した後、solrconfgi.xml内に以下記述を追加してSolrを再起動します。

solrconfig.xml
<queryParser  name="sample" class="org.apache.solr.search.SampleReRankQParserPlugin" />

リランククエリ3

http://localhost:8983/solr/sample01/select?fl=id,payload,weight,score&q=payload:山手&wt=csv&rows=5&sort=weight desc&rq={!sample reRankDocs=3 reRankModulo=2}

id payload weight score 順位 元順位 元score
24 東京 山手線 915 916.61725 1 1 1.6172552
4 恵比寿 山手線 868 869.61725 3 2 1.6172552
15 駒込 山手線 881 1.6172552 2 3 1.6172552
28 田町 山手線 831 1.6172552 4 4 1.6172552
17 西日暮里 山手線 826 1.6172552 5 5 1.6172552
  • 上位3件のうち、2の約数であるid=24,id=4のスコアが 元スコア+weight になっています。

まとめ

ReRankQuery を試した後、フィールド値で上位N件を並び替えるプラグインを作成してみました。
以前、複数フィールド値を加味した独自score計算を実装 したときは、searchComponentから作成したのでとてもめんどくさかったのですが、今回の方法はずっと簡単に実装できました。また、reRankDocsで絞ってから計算を行えるので計算負荷を軽く出来そうです、しかなり使えそうです。

RankQuery にはReRankQueryの他にも、LTR(Learning To Rank)プラグインが既に本家に取り込まれています。LTRプラグインには事前に学習したモデルを使ったソートなど様々な機能が実装されており、そのうちに、こちらのプラグインも試してみたいと思います。

参考

本家の資料
* Query Re-Ranking | Apache Solr Reference Guide 7.2

矢野さんの資料s
* Solr勉強会の時のSlideShare
* Qiitaの記事

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2