実際に取得した四季報データを投入するにあたり、Elasticsearch側で必要な設定をしていきます。
まずElasticsearchですが、以下のような仕組みとなっているそうです。
- RDB: Databases => Tables => Rows => Columns
- Elasticsearch: Indices => Types => Documents => Fields
Developers.IOのブログが非常に参考になりました。
第1回 Elastisearch 入門 インデックスを設計する際に知っておくべき事 | Developers.IO
今回投入するデータは四季報データの1種類だけなので、特段に考慮する部分はないのですが、マッピング定義は手動で実施する必要がありました。マッピング定義とは、RDBにおけるテーブル定義にあたる部分で、投入するデータのフィールドの型や利用するアナライザー、またどのようにElasticsearchへインデクシングさせるか、といった点を定義したものとなります。Elasticsearchはデータを取り込むと自動でマッピングを作成してくれますが、原則手動でマッピング定義は作成すべきみたいです。
以下が今回取り込む四季報のデータです。
“1301”,“作成日:2016年09月16日”,“1301 (株)極洋 きょくよう [水産・農林業]”,“【URL】 http://www.kyokuyo.co.jp/”,“【決算】3月”,“【設立】1937.9”,“【上場】1949.5”,“【特色】水産品の貿易、加工、買い付け主力。すしネタに強み。加工食品は業務用が軸。海外加工比率高い”,“【連結事業】水産商事50(1)、冷凍食品30(0)、常温食品8(2)、物流サービス1(5)、鰹・鮪11(1)、他0(8) <16・3>”,“”,“”,“”,“【大幅増益】冷凍・常温食品は拡大、塩釜新工場本格稼働が奇与。水産商事はサケ・マスなど魚価が安定、加工品が拡大、米国市場も堅調。冷蔵運搬船から撤退し物流効率化。新工場償却負担増でも営業増益。”,“【養殖】完全養殖のクロマグロは18年初に初出荷へ、天然種苗の確保にも全力。業務用冷食では、すし向けなど商品群の拡充を図る。9月末基準日で10株を1株に併合。”,“【業種】 食品 時価総額順位 56/172社”,“【仕入先】KAMEC”,“【販売先】三菱食品”,“【比較会社】1333 マルハニチ,2875 東洋水産,1332 日本水産”,“【本社】107-0052東京都港区赤坂3-3-5TEL03-5545-0701”,“【支社】大阪TEL06-6315-1251,東京,福岡,他”,“【従業員】<16.3>連2,249名 単599名(39.8歳)[年]661万円”,“【証券】[上]東京[幹]日興,野村,大和[名]三菱U信[監]井上”,“【銀行】りそな,農中,三井住友信,三菱U信,三菱U”,“【連結】極洋水産,極洋商事,極洋食品”,“”,“【四半期進捗率】3期平均19.6% 今期13.3%(-6.3%)”,“33702” <
それに合致したマッピング定義として以下を準備しました。
{ "settings": { "index": { "number_of_shards": "1", "number_of_replicas": "0" }, "analysis": { "tokenizer": { "kuromoji": { "type": "kuromoji_tokenizer", "mode": "search" } }, "analyzer": { "kuromoji": { "type": "custom", "tokenizer": "kuromoji", "filter": [ "kuromoji_baseform", "kuromoji_part_of_speech" ] } } } }, "mappings": { "shikiho": { "properties": { "code": { "type": "short", "store": "true" }, "creadtedDate": { "type": "string", "analyzer": "kuromoji", "store": "true" }, "meigaraName": { "type": "string", "analyzer": "kuromoji", "store": "true" }, "url": { "type": "string", "analyzer": "kuromoji" }, "accountingPeriod": { "type": "string", "analyzer": "kuromoji" }, "establishmentDate": { "type": "string", "analyzer": "kuromoji" }, "listingDate": { "type": "string", "analyzer": "kuromoji" }, "feature": { "type": "string", "analyzer": "kuromoji" }, "business": { "type": "string", "analyzer": "kuromoji" }, "assets": { "type": "string", "analyzer": "kuromoji" }, "finance": { "type": "string", "analyzer": "kuromoji" }, "nullColumn1": { "type": "string", "analyzer": "kuromoji" }, "comment1": { "type": "string", "analyzer": "kuromoji", "store": "true" }, "comment2": { "type": "string", "analyzer": "kuromoji", "store": "true" }, "industryType": { "type": "string", "analyzer": "kuromoji" }, "vendor": { "type": "string", "analyzer": "kuromoji" }, "customer": { "type": "string", "analyzer": "kuromoji" }, "rival": { "type": "string", "analyzer": "kuromoji", "store": "true" }, "headOffice": { "type": "string", "analyzer": "kuromoji" }, "branchOffice": { "type": "string", "analyzer": "kuromoji" }, "workerNumber": { "type": "string", "analyzer": "kuromoji" }, "security": { "type": "string", "analyzer": "kuromoji" }, "bank": { "type": "string", "analyzer": "kuromoji" }, "affiliate": { "type": "string", "analyzer": "kuromoji" }, "nullColumn2": { "type": "string", "analyzer": "kuromoji" }, "progress": { "type": "string", "analyzer": "kuromoji" }, "holderNumber": { "type": "integer", "store": "true" } } } } }
mappingの定義と併せて、indexの作成とanalyzerの設定の設定値についても記載しています。
indexの定義ではshardの数を1に、replicaの数を0に設定しています。shardとはElasticsearchサーバ上の、物理的なデータの固まり。デフォルトでは5つに設定されており、通常はこの5つの固まりにindexのデータが分散して格納されて、shard数の単位で平行で処理されることになる、のかな。indexを作成後はshardの数を変更できないのが運用する上では注意点でしょうか。今回は大したデータ量を投入しないので1で設定。replicaについては、その名の通り複製を作成する設定。複数ノードでクラスタを組んでいる場合、自動的に複製を作成してくれるらしいです。なおデフォルトでは1に設定されるため、シングル構成のElasticsearchを構成すると、indexのステータスがyellowになって作成されてしまいます。そのため0に設定。
analyzerについては、以前の投稿を参考。
ElasticsearchのAnalyzerについて - goodbyegangsterのブログ
mappingに関するパラメータは多数あり、正直かなり奥深いです。「どういったデータを取り込むのか」という点と、「どういった検索を実施するのか」という点の双方を考慮して定義を検討する必要があり、ある程度の経験が必要な部分だなと感じました。今回はかなりざっくり設定しています。
パラメータに関しては以下公式を参考。たくさんあります。。。
Mapping | Elasticsearch Reference [2.4] | Elastic
定義情報をmapping.jsonというファイルに記載して、以下コマンドを実行。
# curl -XPOST 'http://localhost:9200/shikiho' -d @mapping.json {"acknowledged":true}
以下のコマンドで確認できます。
# curl 'http://localhost:9200/_cat/indices?v' health status index pri rep docs.count docs.deleted store.size pri.store.size green open shikiho 1 0 0 0 130b 130b # curl 'http://localhost:9200/shikiho?' { "shikiho": { "aliases": {}, "mappings": { "shikiho": { "properties": { "accountingPeriod": { "type": "string", "analyzer": "kuromoji" }, "affiliate": { "type": "string", "analyzer": "kuromoji" }, "assets": { "type": "string", "analyzer": "kuromoji" }, "bank": { "type": "string", "analyzer": "kuromoji" }, "branchOffice": { "type": "string", "analyzer": "kuromoji" }, "business": { "type": "string", "analyzer": "kuromoji" }, "code": { "type": "short", "store": true }, "comment1": { "type": "string", "store": true, "analyzer": "kuromoji" }, "comment2": { "type": "string", "store": true, "analyzer": "kuromoji" }, "creadtedDate": { "type": "string", "store": true, "analyzer": "kuromoji" }, "customer": { "type": "string", "analyzer": "kuromoji" }, "establishmentDate": { "type": "string", "analyzer": "kuromoji" }, "feature": { "type": "string", "analyzer": "kuromoji" }, "finance": { "type": "string", "analyzer": "kuromoji" }, "headOffice": { "type": "string", "analyzer": "kuromoji" }, "holderNumber": { "type": "integer", "store": true }, "industryType": { "type": "string", "analyzer": "kuromoji" }, "listingDate": { "type": "string", "analyzer": "kuromoji" }, "meigaraName": { "type": "string", "store": true, "analyzer": "kuromoji" }, "nullColumn1": { "type": "string", "analyzer": "kuromoji" }, "nullColumn2": { "type": "string", "analyzer": "kuromoji" }, "progress": { "type": "string", "analyzer": "kuromoji" }, "rival": { "type": "string", "store": true, "analyzer": "kuromoji" }, "security": { "type": "string", "analyzer": "kuromoji" }, "url": { "type": "string", "analyzer": "kuromoji" }, "vendor": { "type": "string", "analyzer": "kuromoji" }, "workerNumber": { "type": "string", "analyzer": "kuromoji" } } } }, "settings": { "index": { "creation_date": "1476773695407", "analysis": { "analyzer": { "kuromoji": { "filter": [ "kuromoji_baseform", "kuromoji_part_of_speech" ], "type": "custom", "tokenizer": "kuromoji" } }, "tokenizer": { "kuromoji": { "mode": "search", "type": "kuromoji_tokenizer" } } }, "number_of_shards": "1", "number_of_replicas": "0", "uuid": "-aDPzQlGS_O5OsbthcMDLA", "version": { "created": "2040199" } } }, "warmers": {} } }