ユニークな値を取る

例えばitemのlanguageフィールドからユニークな値を取るにはこう

GET /item/_search
{
  "size": 0,
  "aggs" : {
    "unique_langs" : {
      "terms" : {
        "field" : "language",
        "size" : 500
      }
    }
  }
}

最初のsizeはマッチしたドキュメントを表示する数でここでは0。unique_langsは集計した結果を囲むキー。SQLのASのようなもの。最後のsizeはユニークな値を表示するサイズ。

参照: ElasticSearch - Return Unique Values - Stack Overflow

idの設計で、primary keyのようなことをする

  ,j;;;;;j,. —一、 `  ―–‐、_ l;;;;;;
 {;;;;;;ゝ T辷iフ i    f’辷jァ  !i;;;;;  Elasticsearchにはprimary keyがない・・・
  ヾ;;;ハ    ノ       .::!lリ;;r゙
   `Z;i   〈.,_..,.      ノ;;;;;;;;>  そんなふうに考えていた時期が
   ,;ぇハ、 、_,.ー-、_’,.    ,f゙: Y;;f.   俺にもありました
   ~“戈ヽ   `二´    r’´:::. `!

ElasticsearchにはRDBにおける主キーの仕組みがない。なので、全く同じデータを何度も登録できてしまう。idを指定すれば重複は防げるが、idをインクリメントなどして管理はしたくない。

で、諦めていたが、ドキュメントが一意に決まるfieldの組み合わせからidを作れば良いことがわかった。

つまり、あるドキュメントが、名前と日付で一意に識別できるなら、idを「名前_日付」にしてIndex APIで登録する。

PUT sample/_doc/kimchy_2009-11-15
{
    "user" : "kimchy",
    "@timestamp" : "2009-11-15",
    "message" : "trying out Elasticsearch"
}

ということが、すでにElasticsearch にログを重複・欠損なく格納する案 - Qiitaで言及されていた。 また、時刻を表すfieldはTimelionなどのツールでデフォルトが@timestampになっているので、@timestampで設定するのがよさそう。

スプリットブレイン