the industrial

ブログと言うより自分のためのメモ以外の何モノでもないです。でも読んでくださってありがとうございます。

Elasticsearch入門してます(2日目) データの登録〜簡単なクエリー実行

今日は家に一人でいるのでゆっくりと勉強。

みんなが年末年始で浮かれている間、僕は少しでもElasticsearchに詳しくなって筋肉むきむきになるのだ(しぼうフラグ)。

1日目は、ElasticsearchのインストールからIndexの作成・削除までやった。

引き続き、今日はデータの登録と簡単なクエリーを投げるところまでやりたい。

データの登録

さっそくデータを1件登録してみる。

ここで言うデータとは何になるのか、まだはっきりとは理解していないのだけど、Index、type、documentをそれぞれRDBで言い換えると(なんでもRDBに例えるのは良くない笑)、Database、Table、Columnという感じか。

そしてこれがおそらく基本型。

{HOST}:{PORT}/{index}/{type}/{id} を指定してPUTする。

$ curl -XPUT localhost:9200/events/event/1?pretty -d '
{
  "title" : "TEST-01",
  "createdDate" : "2015-12-29T23:44:20.000Z",
  "updatedDate" : "2015-12-29T23:44:20.000Z"
}'

# ↓戻り値
{
  "_index" : "events",
  "_type" : "event",
  "_id" : "1",
  "_version" : 4,
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "created" : true
}

idが重複するとモチロンエラー。

$ curl -XPUT localhost:9200/events/event/1?pretty -d '
{
  "title" : "TEST-01",
  "createdDate" : "2015-12-29T23:44:20.000Z",
  "updatedDate" : "2015-12-29T23:44:20.000Z"
}'
{
  "_index" : "events",
  "_type" : "event",
  "_id" : "1",
  "_version" : 6,
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "created" : false
}

id値は英数字かな。

$ curl -XPUT localhost:9200/events/event/x?pretty -d '
{
  "title" : "TEST-01",
  "createdDate" : "2015-12-29T23:44:20.000Z",
  "updatedDate" : "2015-12-29T23:44:20.000Z"
}'
{
  "_index" : "events",
  "_type" : "event",
  "_id" : "x",
  "_version" : 3,
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "created" : true
}

ダブルバイトは流石にあかんだろうと思ったら、意外と行けた。

ただ、なんらかの文字化けがおこって登録されているような気がしている...。

$ curl -XPUT localhost:9200/events/event/おみえんど?pretty -d '
{
  "title" : "TEST-01",
  "createdDate" : "2015-12-29T23:44:20.000Z",
  "updatedDate" : "2015-12-29T23:44:20.000Z"
}'
{
  "_index" : "events",
  "_type" : "event",
  "_id" : " ̄チハ ̄チ﾿ ̄チネ ̄ツモ ̄チᄅ",
  "_version" : 1,
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "created" : true
}

データの取得

おそらくコレが最も基本なデータの取得方法。

単純にGETメソッドで取得する。

実際のデータは _source 配下に存在。

ソレ以外のElasticsearch標準項目名は、頭に _ がついた形となっている。

$ curl -XGET localhost:9200/events/event/1?pretty
{
  "_index" : "events",
  "_type" : "event",
  "_id" : "1",
  "_version" : 6,
  "found" : true,
  "_source": {
    "title" : "TEST-01",
    "createdDate" : "2015-12-29T23:44:20.000Z",
    "updatedDate" : "2015-12-29T23:44:20.000Z"
  }
}

さっきのidにxを指定した値

$ curl -XGET localhost:9200/events/event/x?pretty
{
  "_index" : "events",
  "_type" : "event",
  "_id" : "x",
  "_version" : 3,
  "found" : true,
  "_source":
{
  "title" : "TEST-01",
  "createdDate" : "2015-12-29T23:44:20.000Z",
  "updatedDate" : "2015-12-29T23:44:20.000Z"
}
}

そしてダブルバイト。

$ curl -XGET localhost:9200/events/event/おみえんど?pretty
{
  "_index" : "events",
  "_type" : "event",
  "_id" : " ̄チハ ̄チ﾿ ̄チネ ̄ツモ ̄チᄅ",
  "_version" : 1,
  "found" : true,
  "_source":
{
  "title" : "TEST-01",
  "createdDate" : "2015-12-29T23:44:20.000Z",
  "updatedDate" : "2015-12-29T23:44:20.000Z"
}
}

戻ってきた値を見た感じ文字化けが起こっている気もするけど、GETのid指定は おみえんど を指定しているので、単純に表示だけの問題なのか。

ただ、そうだとしてもプログラムでこの値を使うのは無理。

でもまあ、id値にダブルバイト文字を使うことはないと思うから一旦スルーでも良いかな。

データの一括登録

Bulk APIというものがあるのでやってみる。

Bulk API | Elasticsearch Reference [7.4] | Elastic

下記の内容を bulk_events.son というファイル名で定義。

{
  "index": {
    "_index": "events",
    "_type": "event",
    "_id": "3"
  }
}
{
  "title": "TEST-03",
  "createdDate": "2015-12-29T23:44:20.000Z",
  "updatedDate": "2015-12-29T23:44:20.000Z"
}

実行→エラーコンボ。

トライアルアンドエラーは大事。

$ curl -XPOST localhost:9200/_bulk?pretty --data-binary "@bulk_events.json"
{
  "error" : {
    "root_cause" : [ {
      "type" : "json_parse_exception",
      "reason" : "Unexpected end-of-input: expected close marker for OBJECT (from [Source: [B@549930ea; line: 1, column: 0])\n at [Source: [B@549930ea; line: 1, column: 3]"
    } ],
    "type" : "json_parse_exception",
    "reason" : "Unexpected end-of-input: expected close marker for OBJECT (from [Source: [B@549930ea; line: 1, column: 0])\n at [Source: [B@549930ea; line: 1, column: 3]"
  },
  "status" : 500
}

いろいろ調べた結果、prettyな形にしていたのがダメだった様子。

なので、 bulk_events.json の内容を下記にして再実行。

{ "index" : { "_index" : "events", "_type" : "event", "_id" : "3" } }
{ "title" : "TEST-03", "createdDate" : "2015-12-29T23:44:20.000Z", "updatedDate" : "2015-12-29T23:44:20.000Z" }
$ curl -XPOST localhost:9200/_bulk?pretty --data-binary "@bulk_events.json"
{
  "took" : 76,
  "errors" : false,
  "items" : [ {
    "index" : {
      "_index" : "events",
      "_type" : "event",
      "_id" : "3",
      "_version" : 1,
      "_shards" : {
        "total" : 2,
        "successful" : 1,
        "failed" : 0
      },
      "status" : 201
    }
  } ]
}

今度は成功。ちゃんと201で返してくれるんやねえ。

データの更新

更新は割りと簡単なのかな。

先述で登録したid=1のデータのtitleとupdatedDateを更新してみる。

$ curl -XPUT localhost:9200/events/event/1?pretty -d '
> {
>   "title" : "TEST-01_UPDATED",
>   "updatedDate" : "2015-12-30T13:40:44.000Z"
> }'
{
  "_index" : "events",
  "_type" : "event",
  "_id" : "1",
  "_version" : 8,
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "created" : false
}

確認。

$ curl -XGET localhost:9200/events/event/1?pretty
{
  "_index" : "events",
  "_type" : "event",
  "_id" : "1",
  "_version" : 8,
  "found" : true,
  "_source":
{
  "title" : "TEST-01_UPDATED",
  "updatedDate" : "2015-12-30T13:40:44.000Z"
}
}

おうふ。更新は難なく出来たのだけど、CreatedDateが消えた。

(あとちょっと関係ないど、データ登録するときはPOSTメソッドのほうが良いのかな。)

ということで、こんな時は Partial Updateを利用する(シゴトで覚えた)。

Update API | Elasticsearch Reference [7.4] | Elastic

今度はbulkで登録したid=3のデータを更新。

$ curl -XGET localhost:9200/events/event/3?pretty
{
  "_index" : "events",
  "_type" : "event",
  "_id" : "3",
  "_version" : 1,
  "found" : true,
  "_source":{ "title" : "TEST-03", "createdDate" : "2015-12-29T23:44:20.000Z", "updatedDate" : "2015-12-29T23:44:20.000Z" }
}

実行。 _updateがついて、 "doc" を指定しているところに注目。

$ curl -XPOST localhost:9200/events/event/3/_update?pretty -d '{
>     "doc" : {
>       "title" : "TEST-03_UPDATED",
>       "updatedDate" : "2015-12-30T13:50:44.000Z"
>     }
> }'
{
  "_index" : "events",
  "_type" : "event",
  "_id" : "3",
  "_version" : 2,
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  }
}

無事に更新された。

$ curl -XGET localhost:9200/events/event/3?pretty
{
  "_index" : "events",
  "_type" : "event",
  "_id" : "3",
  "_version" : 2,
  "found" : true,
  "_source":{"title":"TEST-03_UPDATED","createdDate":"2015-12-29T23:44:20.000Z","updatedDate":"2015-12-30T13:50:44.000Z"}
}

データの削除

データの削除はチョー簡単。

$ curl -XDELETE localhost:9200/events/event/1?pretty
{
  "found" : true,
  "_index" : "events",
  "_type" : "event",
  "_id" : "1",
  "_version" : 9,
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  }
}

とりあえず今日はここまで。

次はデータを沢山登録して、いよいよ Aggregationをやろうかと。

...と、思っているのだけど、昨日まで昨日が27日とかそのくらいに考えてて、実は明日大晦日だったんですぬ。

omiend.hatenablog.jp

omiend.hatenablog.jp

omiend.hatenablog.jp