LoginSignup
2
1

More than 5 years have passed since last update.

SolrのRandomSortFieldはシード値変更以外でも順番が変わる

Last updated at Posted at 2015-02-10

RandomSortFieldはダイナミックフィールドに設定するシード値以外に次の場合にも順番が変わります

  • ドキュメントが追加されたとき
  • ドキュメントが更新されたとき

要は commitがあってインデックスのversionが上がったとき です。

実装はどうなってるか


org.apache.solr.schema.RandomSortFieldのソースを読んでみると、

...
  /**
   * Given a field name and an IndexReader, get a random hash seed.
   * Using dynamic fields, you can force the random order to change
   */
  private static int getSeed(String fieldName, AtomicReaderContext context) {
    final DirectoryReader top = (DirectoryReader) ReaderUtil.getTopLevelContext(context).reader();
    // calling getVersion() on a segment will currently give you a null pointer exception, so
    // we use the top-level reader.
    return fieldName.hashCode() + context.docBase + (int)top.getVersion();
  }
...

という部分があります。このtop.getVersion()コミットごとに変わる値 です。

public abstract long getVersion()

Version number when this IndexReader was opened.

This method returns the version recorded in the commit that the reader opened. This version is advanced every time a change is made with IndexWriter.

https://lucene.apache.org/core/4_0_0/core/org/apache/lucene/index/DirectoryReader.html#getVersion()

なので、RandomSortFieldでいうシード値とはフィールド名に指定するものだけではなく、 フィールド名のハッシュ+インデックスのバージョン番号 ということになります。

クソ仕様なの?

はじめてこの仕様をみたときは「ランダムゆーてんならフィールド名で指定したシードだけに依存しろや」と思いましたが、よくよく考えてみると理由は推測できます。

Solrをリアルタイムに頻繁に更新するのではなく、 定期的なバッチで更新する場合 はこの仕様のほうが便利です。

シード値を変えるにはクライアント側のコードor設定ファイルを変える必要があります。それにいちいち工数をとるより、データを投入したらランダムソートも一緒に更新されたほうがSolrの管理者としては便利でしょう。

自分の感想はSolr開発側の想定する利用シーンに合ってない使い方をした結果だったわけですね。ま、しょうがないね。

FieldTypeは独自に作ることは自由なんだから、 利用シーンに合わないなら自分でつくりましょう って結論です。フィールド名のみに依存するRandomSortField、つくってるんで完成したら公開しまーす。

追記:自作ランダムソートプラグインの使い方を書きました
更新が多い運用でも使いやすいSolrのランダムソートプラグインを作りました - Qiita

2
1
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
2
1