[Solr] Stored フィールドと DocValued フィールド
Solr の検索処理の要は転置インデックスです。転置インデックスは概念的には以下のようなデータ構造になっています。
キーワード | 文書ID |
製品 | 文書1,文書3,文書4 |
部品 | 文書2,文書5,文書6 |
転置インデックスを使うことで、「部品」を含む文書の文書IDが2と5と6である、といったことを効率良く調べることができます。ただし、利用する機能(ソート、ファセット、ハイライティング)によっては特定のドキュメントに含まれるキーワードを調べるためのデータ構造があると効率が良いことがあります。それが DocValues です。
DocValues は以下のようなデータ構造です。
フィールド名 | 文書ID→フィールド値のマップ |
name | {“文書1″:”製品1”, “文書2″:”部品1”, “文書3″:”製品2”, “文書4″:”製品3”, “文書5″:”部品2”, “文書6″:”部品3”} |
price | {“文書1”:1000, “文書2”:100, “文書3”:2000, “文書4”:3000, “文書5”:200, “文書6”:300} |
すべての文書(あるいは特定の文書セット)における特定のフィールド値をまとめて取得できるデータ構造となっています。
たとえば name:部品 という検索で price フィールドを対象にファセットを作るとします。
この場合、転置インデックスによって「部品」を含む文書IDが2,5,6であることが分かり、それぞれの price フィールドの値が 100,200,300 であることが効率よく調べられます。
DocValues を使うには、対象としたいフィールドの定義で docValues=”true” を指定します。
文書IDからフィールド値を調べるためのデータとしては、フィールド定義で stored=”true” を指定することで格納されたフィールド値も利用できます。stored のデータ構造は以下のようなものです。
文書ID | フィールド名→フィールド値のマップ |
文書1 | {“name”:”製品1″, “price”:1000} |
文書2 | {“name”:”部品1″, “price”:100} |
文書3 | {“name”:”製品2″, “price”:2000} |
文書4 | {“name”:”製品3″, “price”:3000} |
文書5 | {“name”:”部品2″, “price”:200} |
文書6 | {“name”:”部品3″, “price”:300} |
特定の文書IDに紐づくすべてのフィールド値を一括して取得できるデータ構造となっています。
stored=”true” かつ docValues=”false” なフィールドに対してソート、ファセット、ハイライティングといった処理をするために、DocValues に近いデータ構造が FieldCache として Java ヒープ上に作られます。FieldCache は実行時に作られるもので、キャッシュデータが揃うまでに時間が掛かるとかJavaのヒープ使用量が大きくなるとかいった欠点があります。
それに対して DocValues はインデックス作成時に同時に作られます。OSのファイルキャッシュに乗るため、実行時のコストを小さくすることができます。