elasticパッケージでRからElasticsearchを使う
前回のTokyo.RでElasticsearchを使うためのRのパッケージがあると聞きました。調べてみると、信頼と安心のrOpenSciがパッケージをつくってました。
ということで、ちょっと使ってみます。
Elasticsearchのインストール
ローカルにインストールする場合
elasticパッケージのREADMEにいろいろやり方が書いてあります。手元にDockerがあるなら、公式イメージがあるのでお手軽でいいかも。
https://github.com/ropensci/elastic#install-elasticsearch
別マシン(VPSとか)にインストールする場合
メモったのでこっちを参考にしてください。
外からアクセスできるようにするには、ポートを変えといた方が安全です。たぶん。/etc/elasticsearch/elasticsearch.yml
に以下の設定を追加します。XXXX
には適当なポート番号を入れてください。
http.port: XXXX
設定を書き換えたらElasticsearchを再起動します。
sudo service /etc/init.d/elasticsearch restart
あと、ファイアウォールにもそのポートの通信は通すように設定をしましょう。ufwならこんな感じです。
sudo ufw allow in XXXX/tcp
elasticをインストール
参考:https://github.com/ropensci/elastic#install-elasticsearch
CRANにはないみたいなので、devtoolsでインストールします。
devtools::install_github("ropensci/elastic")
elasticの設定
参考:https://github.com/ropensci/elastic#initialization
ElasticsearchのAPIを使う前に、connect()
という関数を使ってIPやポートを指定するみたいです。(ローカルでElasticsearchを動かす場合はデフォルトのままで動くので不要)
library(elastic) connect(es_base = "http://XX.XX.XX.XX", es_port = XXXX)
使ってみる
とりあえずテスト用にデータを入れてみます。
plosdat <- system.file("examples", "plos_data.json", package = "elastic") docs_bulk(plosdat)
例えば、id
を指定してひとつだけドキュメントをもってくるにはdocs_get()
を使います。
docs_get(index = 'plos', type = 'article', id = 4)
これは、Document APIのGet APIのラッパーなわけですが、だいたいのAPIのラッパーは
APIの種類_操作()
という名前で用意されています。Search()
とかexplain()
とか、変則的なのもあるみたいですけど。だいたいの操作はRからでやれそうな雰囲気です。
ls('package:elastic') #> [1] "alias_create" "alias_delete" "aliases_get" #> [4] "alias_exists" "alias_get" "cat_" #> [7] "cat_aliases" "cat_allocation" "cat_count" #> [10] "cat_fielddata" "cat_health" "cat_indices" #> [13] "cat_master" "cat_nodes" "cat_pending_tasks" #> [16] "cat_plugins" "cat_recovery" "cat_segments" #> [19] "cat_shards" "cat_thread_pool" "cluster_health" #> [22] "cluster_pending_tasks" "cluster_reroute" "cluster_settings" #> [25] "cluster_state" "cluster_stats" "connect" #> [28] "connection" "count" "docs_bulk" #> [31] "docs_create" "docs_delete" "docs_get" #> [34] "docs_mget" "es_parse" "explain" #> [37] "field_mapping_get" "index_analyze" "index_clear_cache" #> [40] "index_close" "index_create" "index_delete" #> [43] "index_exists" "index_flush" "index_get" #> [46] "index_open" "index_optimize" "index_recovery" #> [49] "index_segments" "index_settings" "index_stats" #> [52] "index_status" "index_upgrade" "mapping_create" #> [55] "mapping_delete" "mapping_get" "mlt" #> [58] "nodes_hot_threads" "nodes_info" "nodes_stats" #> [61] "ping" "scroll" "Search" #> [64] "search_shards" "tokenizer_set" "type_exists"
クエリは、listを指定することも、JSONの文字列を指定することもできます。下の2つは同じです。
body <- list(query = list(query_string = list(query = "cell")), highlight = list(fields = list(title = list(number_of_fragments = 2)))) out <- Search('plos', 'article', body=body)
body <- '{ "query": { "query_string": { "query" : "cell" } }, "highlight": { "fields": { "title": {"number_of_fragments": 2} } } }' out <- Search('plos', 'article', body=body)
ということで、かなり便利っぽいです。ただ、返ってくるデータ形式はネストしたリストなので、ちょっと前処理しないとRでの分析には使えなさそうです。。
rlist
ガチ勢のひとに期待しつつこのへんで筆を置くことにします。
str(out, max.level = 3) #> List of 4 #> $ took : int 169 #> $ timed_out: logi FALSE #> $ _shards :List of 3 #> ..$ total : int 5 #> ..$ successful: int 5 #> ..$ failed : int 0 #> $ hits :List of 3 #> ..$ total : int 58 #> ..$ max_score: num 1.25 #> ..$ hits :List of 10 #> .. ..$ :List of 7 #> .. ..$ :List of 7 #> .. ..$ :List of 7 #> .. ..$ :List of 7 #> .. ..$ :List of 7 #> .. ..$ :List of 7 #> .. ..$ :List of 7 #> .. ..$ :List of 7 #> .. ..$ :List of 7 #> .. ..$ :List of 7