Elasticsearchを使う

CentOS7にインストール

www.elastic.co

バージョン

Elasticsearch 7.0.1
Kibana 7.0.1

データをInsertする

curl -H 'Content-Type:application/json' -XPOST 'localhost:9200/logs/_doc?pretty' -d '
{
  "value": 1000,
  "recorded_at": "2019-05-09 08:00:00"
}'
  • Kibana console
POST logs/_doc
{
  "value": 1000,
  "recorded_at": "2019-05-09 09:10:00"
}

mappings

自動でマッピングもされるが、datetime型のテキストを入れてもtext型でマッピングされてしまう。

{
  "mapping": {
    "properties": {
      "value": {
        "type": "long"
      },
      "recorded_at": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      }
    }
  }
}

datetime形式はマッピング定義を事前に作成しておく。

PUT logs
{
  "mappings": {
    "properties": {
      "value": {
        "type": "integer"
      },
      "recorded_at": {
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss"
      }
    }
  }
}
  • string text型とkeyword型の違い
    ・text型はAnalyzerによって単語に分割されてインデックスされるので、部分一致で検索できる。
    ・keywordは完全一致で検索される。デフォルトでignore_above: 256 のパラメータが付与され、256文字以上はインデックスされない。

bulk insert

POST logs/_bulk
{"index":{"_index":"logs"}}
{"value":1000,"recorded_at":"2019-05-09 08:00:00"}

AutoIndentで整形するとエラーになるので注意
sora-sakaki.hatenablog.com

curlでbulkinsertする

curl -H 'Content-Type: application/json' -XPOST 'localhost:9200/logs/_bulk?pretty' -d '
{"index":{"_index":"logs"}}
{"value":1000,"recorded_at":"2019-05-09 08:00:00"}
{"index":{"_index":"logs"}}
{"value":1000,"recorded_at":"2019-05-09 08:00:00"}
'

最後の'に注意

{
  "error" : {
    "root_cause" : [
      {
        "type" : "illegal_argument_exception",
        "reason" : "The bulk request must be terminated by a newline [\\n]"
      }
    ],
    "type" : "illegal_argument_exception",
    "reason" : "The bulk request must be terminated by a newline [\\n]"
  },
  "status" : 400
}

phpでGuzzleを使ってelasticsearchにPOSTする

stackoverflow.com

<?php
        $client = new Client();
        $data = null;
        foreach ($logs as $log) {
            $json_data = [
                json_encode(['index' => ['_index' => 'logs']]),
                json_encode(['value' => $log[0], 'recorded_at' => $log[1]])
            ];
            $data[] = join("\n", $json_data);
        }
        $data = implode("\n", $data);
        $client->post('http://localhost:9200/logs/_bulk?pretty',
            [
                'headers' => ['Content-Type' => 'application/json'],
                'body' => $data . "\n"
            ]
        );

大量にデータを入れる場合

・コミットメントの頻度を変更

{
  "index.blocks.read_only_allow_delete": "false",
  "index.priority": "1",
  "index.query.default_field": [
    "*"
  ],
  // 1s → 30sに変更
  "index.refresh_interval": "30s",
  "index.write.wait_for_active_shards": "1",
  "index.number_of_replicas": "1"
}

qiita.com

インデックステンプレート

ログをインデックスする場合に、インデックス名を logs-yyyy-mm-dd といった形で保存したい場合に使う。

logs-*にマッチするインデックスに自動的にマッピングされる

PUT _template/logs
{
  "index_patterns": ["logs-*"],
  "settings": {
    "index.refresh_interval": "30s",
    "number_of_shards": "5",
    "index.number_of_replicas": "0"
  },
  "mappings": {
    "dynamic": false,
    "properties": {
      "value": {
        "type": "integer"
      },
      "recorded_at": {
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss"
      }
    }
  }
}

qiita.com www.sambaiz.net