Lucene/Solr で フィールドに入っているユニークな値の数を求めたい場合があります. たとえばユニークユーザ数を求める場合です.

初級編

FieldCollapsing - Solr Wiki を利用します.

group.ngroups パラメータを true に指定するとクエリにマッチするグループの数を出力してくれます.

/solr/select?group=true&group.field=[フィールド名]&group.ngroups=true&...

1日1.5億PV/数百万UU 1時間最大1千数百万PV/百万UU という想定で, 1時間のUUを(qパラメータで時間を区切って)求めると, 数十秒(1分越えることもある)で得られました.

中級編

上記の想定では1日のUUを求めるにはちょっと重たそうです.

ここで Solr のコアは1日ごとに別々だとします.

コア単位でフィールドのユニークな値を求めるのに, LukeRequestHandler - Solr Wiki が利用できます.

/solr/admin/luke?fl=[フィールド名]

Solr Wiki のページを distinct で検索してもらえればわかりますが, フィールドのユニークな値の数が得られます.

上記の想定で1日のUUをこの方法で求めると, 10秒前後でした.

上級編

もし, 1時間のUUも初級編の方法では時間がかかりすぎる, 中級編であればいけるという場合はどうしたらいいでしょうか.

この場合は検証してないのですが, 1時間ごとにコアを作成することになるでしょう. 1時間ごとのUUはそのまま LukeRequestHandler を用います. 1日のUUは, インデックスをマージしてやはり LukeRequestHandler で求めます.

Solr のインデックスのマージについては MergingSolrIndexes - Solr Wiki に記述されています.

もしくは, 特定のフィールドの値が複数の shard に入らないようにして適当にするでしょうか.