バツイチちゃんがSolrのこと書いてたので、インケンはElasticsearchのこと書きます。
xmlよりjson派なインケンとしてはsolrなんかより、elasticsearch押しです。solr使ったことないけどね!
elasticsearchはRESTリクエスト飛ばせば、検索登録更新削除すべて行うことができるのですが、RabbitMQのプラグインを使うと、登録更新削除をキューにメッセージ投げるだけでいいので、大変便利です。
MQにメッセージ投げる際には、elasticsearchのbulk api形式で送る必要があります。
その辺がわかりづらかったので、サンプル交えてご紹介します。
elasticsearch、rabbitmqプラグインのインストールは割愛します。
elasticsearchにrabbitmq用のインデックスを登録する
まずはelasticsearchにrabbitmqのサーバー情報を設定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | "type" : "rabbitmq" , "rabbitmq" : { "host" : "192.168.0.1" , "port" : 5672, "user" : "guest" , "pass" : "guest" , "vhost" : "/" , "queue" : "elasticsearch" , "exchange" : "elasticsearch" , "routing_key" : "elasticsearch" , "exchange_declare" : true , "exchange_type" : "direct" , "exchange_durable" : true , "queue_declare" : true , "queue_bind" : true , "queue_durable" : true , "queue_auto_delete" : false , "args" : { "x-ha-policy" : "all" } }, "index" : { "bulk_size" : 100, "bulk_timeout" : "10ms" , "ordered" : false } }' |
RabbitMQを冗長化してる場合はこんな感じ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | "type" : "rabbitmq" , "rabbitmq" : { "addresses" : [ { "host" : "rabbitmq-host1" , "port" : 5672 }, { "host" : "rabbitmq-host2" , "port" : 5672 } ], "user" : "guest" , "pass" : "guest" , ...... ..... }' |
これでmqにelasticsearchっていうキューができます。
RabbitMQ経由でデータを登録変更削除する
サンプルとして以下のインデックスを想定します。
1 2 3 4 5 6 7 8 9 | { "photo" : { "properties" : { "caption" : { "type" : "string" }, "upload_datetime" : { "type" : "date" , "format" : "yyyy-MM-dd HH:mm:ss" } } } }' |
これにデータを登録する場合、MQにこんな感じでメッセージを投げます。
PHPサンプル
1 2 3 4 5 6 | //登録、変更 $message = '{ "index" : { "_index" : "google", "_type" : "photo", "_id" : "' . $photo_id . '" } }' . '\n' ; $message .= '{ "photo" : { "caption" : "写真の説明だよ" , "upload_datetime" :"' . date ("Y-m-d H:i:s ").'" }}' . '\n' ; $message .= '{ "create" : { "_index" : "google", "_type" : "photo", "_id" : "' . $photo_id . '" } }' ; publish_mq( 'elasticsearch' , $message ); //MQに投げる処理 |
登録と変更は同じです。すでにIDが存在すると更新になります。
1 2 3 | //削除 $message = '{ "delete" : { "_index" : "google", "_type" : "photo", "_id" : "' . $photo_id . '" } }' . '\n' ; $message .= '{ "create" : { "_index" : "google", "_type" : "photo", "_id" : "' . $photo_id . '" } }' ; |
ポイントは、改行です。
JSONでOKなんだと思って、以下のように一行で投げるとエラります。
1 2 | //これNG $message = '{ "delete" : { "_index" : "google", "_type" : "photo", "_id" : "' . $photo_id . '" } , "create" : { "_index" : "google", "_type" : "photo", "_id" : "' . $photo_id . '" } }' ; |
そして上記のサンプルの場合、captionってデータに改行コードが入ってるとエラるので、それも除去してあげる必要があります。
いかがでしょうか、もちろんRESTでelasticsearchに直接データをPOSTすることもできますが、すべて一旦MQに投げとくと処理待ちも回避できて良いと思います。