とーますメモ

Ruby on Rails / Goなどの学習メモ

【Elasticsearch】データをElasticsearchに入れる方法について調べてみた

多くのサイトで以下のデータセットを使っているケースが多い。

github.com

この記事ではこのデータセット使用させて頂き
データをElasticsearchに入れる方法について解説する。

調べてみたところ、データの注入方法としては
以下の方法があるようだ。

  1. River系プラグインRDBからデータを入れる
  2. River系プラグインCSVからデータを入れる
  3. Bulk APIを使用する
  4. Index APIを使用する

1) River系プラグインRDBからデータを入れる

elasticsearch-jdbcというツール(元はプラグイン?)を使って
データを入れるというの主流っぽい。

qiita.com

ただしこの「elasticsearch-jdbc」は、現時点(2017/08/21)で
Elasticsearchの2.3.4までにしか対応していない。

※以下公式内の「Compatiblity matrix」箇所を参照
github.com

ちなみに現在の2.x系の最新版は「2.4.6」。

最新版の2.x系や5.x系を使用する場合、上手く動作しないっぽい。
※自分は2.4.6で試してみたが、動作しなかった。

2) River系プラグインCSVからデータを入れる

以前は、以下のプラグインを使ってCSVからデータを入れていたようだが
riverの廃止により、1.7.x系までしかサポートしていない。
1)の方法と同じように、最新版の2.x系や5.x系を使用する場合、上手く動作しないっぽい。

github.com

以下公式より引用

As from ES version 2 and above, rivers are not supported anymore. This said we've discontinued this repo for active development and let it be only for important fixes.

3)Bulk APIを使用する

JSONファイルを作成し、一気にバルクインサートする。
以下のサイトさんが詳しく解説している。

qiita.com

ameblo.jp

ただこのJSONファイルを作るのも、ちょっと面倒くさい。
専用のDSLに沿ったJSONを書かないといけないので、
JSONファイルを作成するためのコードを別途作成必要がある。

elasticsearch用jsonを作成せずとも、単純なデータだけのjson
データを注入できる「steam2es」というツールもあるらしい。
以下のサイトさんが解説している。

blog.johtani.info

ちなみに公式から
各言語に対応したクライアントも出ている。

Rubyだとこんな感じかと。(未検証)

①インストール

gem install elasticsearch

②コード作成

# デフォルトでlocalhost:9200に接続
client = Elasticsearch::Client.new log: true
# HOSTやURLを指定したい場合は以下。
# client = Elasticsearch::Client.new host: 'search.myserver.com'
# client = Elasticsearch::Client.new host: 'myhost:8080'
# client = Elasticsearch::Client.new url: 'https://username:password@api.server.org:4430/search'

client.bulk body: [
  { index:  { _index: 'myindex', _type: 'mytype', _id: 1, data: { title: 'foo' } } },
  { update: { _index: 'myindex', _type: 'mytype', _id: 2, data: { doc: { title: 'foo' } } } },
  { delete: { _index: 'myindex', _type: 'mytype', _id: 3  } }
]

[参考]
https://github.com/elastic/elasticsearch-ruby/blob/master/elasticsearch-api/lib/elasticsearch/api/actions/bulk.rb
http://inokara.hateblo.jp/entry/2015/12/14/231143


4)Index API

自分の場合は、手軽くデータを入れたかったので
この方法に落ち着いた。

以下のサイトさんのやり方を参考にRubyコードを作成
easyramble.com

①コード(insert_data.rb)の作成

#!/usr/bin/env ruby

require "csv"

CSV.open("restaurants.csv", "r") do |f|
  f.each_with_index do |item, i|
    next if i == 0
    p item
    `curl -XPUT 'http://localhost:9200/ldgourmet/restaurant/#{item[0]}' -d '
      {
        "id": "#{item[0]}",
        "name": "#{item[1]}",
        "property": "#{item[2]}",
        "alphabet": "#{item[3]}",
        "name_kana": "#{item[4]}",
        "pref_id": "#{item[5]}",
        "area_id": "#{item[6]}",
        "station_id1": "#{item[7]}",
        "station_time1": "#{item[8]}",
        "station_distance1": "#{item[9]}",
        "station_id2": "#{item[10]}",
        "station_time2": "#{item[11]}",
        "station_distance2": "#{item[12]}",
        "station_id3": "#{item[13]}",
        "station_time3": "#{item[14]}",
        "station_distance3": "#{item[15]}",
        "category_id1": "#{item[16]}",
        "category_id2": "#{item[17]}",
        "category_id3": "#{item[18]}",
        "category_id4": "#{item[19]}",
        "category_id5": "#{item[20]}",
        "zip": "#{item[21]}",
        "address": "#{item[22]}",
        "north_latitude": "#{item[23]}",
        "east_longitude": "#{item[24]}",
        "description": "#{item[25]}",
        "purpose": "#{item[26]}",
        "open_morning": "#{item[27]}",
        "open_lunch": "#{item[28]}",
        "open_late": "#{item[29]}",
        "photo_count": "#{item[30]}",
        "special_count": "#{item[31]}",
        "menu_count": "#{item[32]}",
        "fan_count": "#{item[33]}",
        "access_count": "#{item[34]}",
        "created_on": "#{item[35]}",
        "modified_on": "#{item[36]}",
        "closed": "#{item[37]}"
      }
    '`
  end
end

パーミッションの設定

$ chmod 755 insert_data.rb

③データ挿入

$ ruby insert_data.rb

ちょっと時間かかるけど、シンプルで楽だった。

【Elasticsearch】活用例・用途について調べてみた

調べてみた感じだと以下のような用途で使用されている。

  1. 検索レスポンスの向上
  2. ログ解析・管理
  3. Webクローラとして使用


実践的な活用例としては以下の例が、素晴らしいと思う。

www.slideshare.net

www.slideshare.net


1)検索レスポンスの向上

RDBのインデックス対応などを施してみても
検索レスポンスが向上しない場合などに、使用されるケースが想定される。

RDBのVIEWから読み出したデータをElasticsearchに貯めて
検索させるとかすれば早くなりそう。

ただリアルタイムでRDBとElasticsearchのデータが同期するわけではないので
トランザクションデータなどリアルタイムで同じデータが検索したい場合などは
あまり不向きか。
あくまでもマスタデータなど余り変更が無いデータなどの検索などに向いていると思わる。
※リアルタイム性が特に必要のないのであれば、
同期のインターバルを10分〜30分にするなどすれば、ましになるか。。

このケースだと、WordPressとの連携も可能。

thoames.hatenadiary.jp

2)ログ解析・管理

アクセスログ、エラーログ、SQL系のログなど
色んなログを一箇所でまとめて管理し、グラフ化するといった用途で使用される。
ネットで情報を見る限り、Elasticsearchの利用例はこのケースが一番多い気がする。

3)Webクローラとして使用

以下のようなプラグインを使用することで
Elasticsearchを独立したクローラとして使用できる。
大量のデータをクロールし、検索レスポンスも早いので
通常のWeb技術で作るより、メリットがあると思われる。

github.com

【Elasticsearch】爆速検索!WordPressとの連携方法

つい先日、「WORDCAMP KYOTO 2017」の

WordPressにElasticsearchを連携してみた話」という動画を拝見させて頂いた。

 

WordPress検索のデフォルトではインデックスが効かない「LIKE検索」を採用しているため、記事が増えたときに検索がどうしても遅くなってしまうが、

Elasticsearchを用いての検索は体感で実感できるぐらい、かなり検索が早くなる。
動画の中ではWooCommerceとの連携についても少し話が上がっているが

正にうってつけなソリューションだと思う。

 

せっかくなので具体的なやり方や、

他にどういった連携方法があるのかなどについて調査してみた。

 

wordpress.tv

1.Elasticsearchの基本的な知識がまずは必要

言わずもがな、まずはElasticsearchの基礎知識は必要。

環境設定、インデックスの作り方、クエリの書き方は

とりあえずは必要。

 

thoames.hatenadiary.jp

2. Elasticsearchと連携可能なプラグインを使用する

上記の「WordPressにElasticsearchを連携してみた話」では

以下の「WP Simple Elasticsearch」というプラグインを使用して

WordPressとの連携を行っている。

 

github.com

他にも調べてみたところ、

「Fantastic Elasticsearch」というプラグインが有名みたい。

 

github.com

他にも「Wp-Elasticsearch」というプラグインもあるみたいだが、

こちらは入れると警告が出る。。ソースを読んでみたがPHPの古い記述方式で書かれていたので、恐らくメンテされてないっぽい。

 

Wp-elasticsearch by searchbox-io

 

「Fantastic Elasticsearch」は結構他のブログさんでも紹介されており

自分も実際、入れてみたが綺麗なUIで使いやすそうな印象。

 

【WordPress】Fantastic Elasticsearchを導入してみた

Fantastic ElasticSearchプラグインを入れてみた

 

上記の「Fantastic Elasticsearch」の改造版として

「Kumihimo」というプラグインも検索にひかかったが

作者のページが存在せす、特に何をどう変更したのかが不明。

wordpress.org

3.まとめ

 

  • プラグインを使うなら「WP Simple Elasticsearch」か「Fantastic Elasticsearch」が良さげ。※改造して使うなら「WP Simple Elasticsearch」のほうが、改造しやすい。
  • WooCommerceとの連携に良さげ。

 

 

【WordPress】サッっと作成!設定画面用のフレームワーク

WordPressでテーマやプラグインで設定画面のUI作成するときに

クラッチで作成しようとしている方へ。

 

自分は、あるプラグインのソースを読んでいて

設定画面用のFrameworkがあることに気づいた。

 

以下のサイトあたりが詳しそう。

 

www.wpexplorer.com

 

wpcrux.com

 自分はNHP Theme Options Frameworkというのを使うことにしました。

公式のWikiが凄い不親切だけど、ネットで情報を集めながら使えばなんとか使えそう。

 

github.com

 

wpsquare.com

 

 

 

 

 

【Elasticsearch】概要について理解する

Elasticsearchが何かをネットで調べるとよく「全文検索エンジン」という言葉を
目にするかと思うが、正直、自分の場合はよくわからなかった。
このページでは、Elasticsearchの概要について解説する。

全文検索エンジンとは?

Wikipediaによると以下のようにある。

全文検索エンジンの一つ。
全文検索とは、コンピュータにおいて、複数の文書(ファイル)から特定の文字列を検索すること。「ファイル名検索」や「単一ファイル内の文字列検索」と異なり、「複数文書にまたがって、文書に含まれる全文を対象とした検索」という意味で使用される。

by Wikipedia

なるほど。「複数文書にまたがって、文書に含まれる全文を対象とした検索」とな。。
この文章だけだと、なんか検索に凄い時間がかかりそうな気がするが
調べてみると全文検索エンジンには以下のタイプがある模様。

1)grep

ファイルを一つずつ順番に検索対象になるかをチェックしていく方法
ファイルが増えると、速度が低下する模様。そりゃそうだろう。

2)索引(インデックス)型

予め検索対象となる文章郡を走査しておき、高速な検索が可能になるような索引データを準備しておき
検索時にはこの索引データを対象にした検索を行うことで、検索の高速化を図る方法。
Elasticsearchはこの索引型。

索引(インデックス)の作成方法

文書から索引を作成するとき、文章から「単語」を抽出する。
この抽出された単語と文書を紐付けて索引データ(転置ファイルとも言うらしい)を作成するが
日本語の場合、英語などと違い文書の間にスペースなどの単語を区切る目印が無いため
適切な単語を抽出することが難しい。

そこで日本語の場合は以下の方法で単語を抽出する。

1)N-gram

この方法により適切な単語が抽出されるとは限らないが
N(1以上の数字)文字ずつ文書を区切り、その文字列を索引とする。
次の形態素解析と比べて、ただ指定された数字単位で文字を区切るだけなので早そう。

2)形態素解析

辞書データを用いることで実際に使用される単語を抽出する。
前のN-gramと比べて、辞書と比較しながら索引を作るのでちょっと遅そう。

レンタルサーバへのインストールは・・・

検索する限り、レンサバへインストールしている例はないっぽい。
メモリを食うなどの理由もしくはそもそも無理なのか。。
Elasticsearchをインストールする際は、VPSなどサーバを別途に立てて
使用したほうが良いと思われる。

まとめ

  • Elasticsearchとは「索引型」の「全文検索エンジン」の一種である。
  • 索引型の全文検索エンジンでは索引を作成するため、文章から単語を抽出し、索引データを作成する必要がある。

【MySQL】レプリケーション設定をリモート(Master)-> ローカル(Slave)で設定

ローカル(開発用)環境のMySQLのデータと
リモート(ステージング)環境のMySQLデータを同期させたいという思いから
色々と情報をネット上で検索してみたのだが、
大体のレプリケーション設定は同一のネットワーク上で設定することが
前提とされているものが多かったため、自分用にメモ。

前提知識

よく利用するコマンド

コマンド 機能 DB
SLAVE START USER='' PASSWORD='' レプリケーションの開始/再開 Slave
SLAVE STOP レプリケーションの停止 Slave
RESET SLAVE Salveの状態のリセット Slave
SHOW MASTER STATUS¥G マスターの状態を表示 Master
SHOW SLAVE STATUS¥G スレーブの状態を表示 Slave

※「¥G」は表示を縦並びで表示させるために使用。

基本は以下のサイトのように設定するが
MySQLでMaster-Slave構成のレプリケーション設定 - Qiita
Slaveアカウントの作成のやり方が少し違う。

やり方は以下のサイトを参考にする。
SSH経由でMySQLの準同期レプリケーションを行う方法 | 株式会社田村倉庫

Slaveアカウントを作成

作成するユーザーはスレーブがマスタのバイナリ ログを読み込むときに接続するユーザーとなる。
またSSHポートフォワーディングを利用したアクセスになるため
ホストは「localhost」として設定する。

設定例)

ホスト ユーザ パスワード
localhost slave password
GRANT REPLICATION SLAVE ON *.* TO slave@'localhost' IDENTIFIED BY 'password';

Slave DBの設定

Slave DBでMaster DBへ接続するためのパラメータを設定。
設定の仕方は以下の2通りが存在する

  1. change master コマンドでの設定例
mysql> change master to
    -> master_host='localhost',          # Master DBサーバのホスト名/IPアドレス
    -> master_log_file='xxxxxx-bin.000001',  # バイナリログのファイル名
    -> master_log_pos=xxx;                   # バイナリログの現在位置

※master_user='slave'とmaster_password='password'は、
上記のchange masterコマンド実行時に設定できるが、セキュリティの関係上
Salve Start時に「START SLAVE user='slave' password='password'」として実行する。


change masterコマンドを実行すると、
master.infoというファイルが作成され、中身を見ると設定内容が確認できる。

  1. my.cnfに設定する


change masterコマンドで設定する場合
オンラインで設定を更新できるというメリットがある。
設定内容があまり変わらない場合は、my.cnfに設定するという方法もありか。


SSHポートフォワーディングの設定

「slave start」を行う前に、この設定を行う。

下記の設定を行うことにより、ローカルからホスト名(localhost)+ポート番号(10000)にアクセスすることで
リモートサーバ内のMySQL(ポート番号:3306)にアクセスできる。

ssh -f -N -C -L 10000:localhost:3306 リモートSSHユーザ名@リモートホスト名 -p リモートのポート番号
オプション 説明
-f このポートフォワーディングをバックグラウンドで実行する。(必須)
-N SSHトンネリングのみに使用する。(必須)
-C データを圧縮して送る。

下記を参考
SSH経由でMySQLの準同期レプリケーションを行う方法 | 株式会社田村倉庫
SSHのポートフォワーディングでMySQLに接続する方法 | 株式会社田村倉庫
社壊人エンジニア備忘録: mysqlのリモートレプリケーション

レプリケーションフィルタ

DB、テーブル単位で変更できる。
my.cnfに設定するパターンと
オンラインで変更することも可能