実際に取得した四季報データを投入するにあたり、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": {}
}
}