Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
24
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

@yuukigoodman

Yokozuna ~期待の全文検索機能~

「RiakってKVSなんでしょ?そんなん使いどころ少ないし(゚⊿゚)イラネ」
「結局やっぱ検索が重要だし、mongoじゃないとねー」
そんなふうに思っているアナタに贈るRiak2.0注目の新機能。
みんなでやるRIak Advent Calendar7日目は、全文検索機能Yokozunaの紹介だ。

Yukozunaの概要

端的に言うと、全文検索エンジンApache Solrの管理をRiakで行うというものだ。
RiakにストアされたデータからSolrのインデックスを作成する。
データの管理もインデックスの管理もRiakが行う。
また、Solrの死活監視もRiakが行う。
これによって実現されるのは、強力な検索機能を持った落ちないDB。
それがYokozuna。

なんでYokozunaという名前なのか

README曰く、

Horizontal rope. The top rank in sumo, usually translated Grand Champion. The name comes from the rope a yokozuna wears.
The goal of the Yokozuna application is to integrate Apache Solr with Riak in order to find the "top rank" documents for a given query.

一番最初が"横の綱"という説明で、外国の人がわかるのだろうか...
字面そのままじゃね...?

という揚げ足取りはさておき、Riak YokozunaにはTop Rankになってほしいものだぜ!!

セットアップ

YukozunaのREADMEに従えば簡単だ。
Erlang R15B03以上、Java 1.6以上が必要なので注意。
ちなみに、推奨は16B02、Oracle 7u25らしい。
今回はR15B03-1とOpenJDK 1.7なのでどうなんだろ...
クラスタを試してもいいけど、使ってみたいだけなのでとりあえずシングルノードで。
起動前に、設定を書き換えておく。

[vagrant@localhost riak]$ sed -e 's/search = off/search = on/' -i.back rel/riak/etc/riak.conf

いつものように起動する

[vagrant@localhost riak]$ rel/riak/bin/riak start
[vagrant@localhost riak]$ rel/riak/bin/riak ping
pong

とりあえず使ってみよう

Yokozunaを使うには、最初にBucket Typeを作成する必要がある。
これについては二日目にBucket Typesを参考にしてほしい。

[vagrant@localhost riak]$ rel/riak/bin/riak-admin bucket-type \ 
> create my_type '{"props":{"search_index":"my_index"}}'
my_type created

[vagrant@localhost riak]$ rel/riak/bin/riak-admin bucket-type \
> activate my_type
my_type has been activated

で、次にインデックスを設定する。

[vagrant@localhost riak]$ curl -XPUT -i 'http://localhost:8098/search/index/my_index'
HTTP/1.1 204 No Content
Server: MochiWeb/1.1 WebMachine/1.10.5 (jokes are better explained)
Date: Sat, 07 Dec 2013 14:24:22 GMT
Content-Type: application/json
Content-Length: 0

あとはデータを入れるだけで、良い感じにインデキシングしてくれる。

[vagrant@localhost riak]$ curl -H 'content-type: text/plain' \
> -X PUT 'http://localhost:8098/types/my_type/buckets/my_bucket/keys/name' \
> -d "saisa 6153"

クエリを投げるとxmlが帰ってくる。

[vagrant@localhost riak]$ curl 'http://localhost:8098/search/my_index?q=text:saisa'
<?xml version="1.0" encoding="UTF-8"?>
<response>
<lst name="responseHeader"><int name="status">0</int><int name="QTime">16</int><lst name="params"><str name="shards">127.0.0.1:8093/solr/my_index</str><str name="q">text:saisa</str><str name="fq">(_yz_node:riak@127.0.0.1 AND (_yz_pn:63 OR (_yz_pn:60 AND (_yz_fpn:60)) OR _yz_pn:59 OR _yz_pn:56 OR _yz_pn:53 OR _yz_pn:50 OR _yz_pn:47 OR _yz_pn:44 OR _yz_pn:41 OR _yz_pn:38 OR _yz_pn:35 OR _yz_pn:32 OR _yz_pn:29 OR _yz_pn:26 OR _yz_pn:23 OR _yz_pn:20 OR _yz_pn:17 OR _yz_pn:14 OR _yz_pn:11 OR _yz_pn:8 OR _yz_pn:5 OR _yz_pn:2))</str></lst></lst><result name="response" numFound="1" start="0" maxScore="0.8784157"><doc><str name="_yz_id">my_type_my_bucket_name_41_2bc30rswtUNBw8YGIg9NWb</str><str name="_yz_rk">name</str><str name="_yz_rt">my_type</str><str name="_yz_rb">my_bucket</str></doc></result>
</response>

僕はsolrに不慣れなのでよくわからないが、numFoundを見るとちゃんと機能しているっぽいことがわかる。

[vagrant@localhost riak]$ curl -H 'content-type: text/plain' \
> -X PUT 'http://localhost:8098/types/my_type/buckets/my_bucket/keys/name' \
> -d "saisa 6154"
[vagrant@localhost riak]$ curl -H 'content-type: text/plain' \
> -X PUT 'http://localhost:8098/types/my_type/buckets/my_bucket/keys/name' \
> -d "saisa 6155"
[vagrant@localhost riak]$ curl -H 'content-type: text/plain' \
> -X PUT 'http://localhost:8098/types/my_type/buckets/my_bucket/keys/name' \
> -d "saisa 6156"

[vagrant@localhost riak]$ curl 'http://localhost:8098/search/my_index?q=text:saisa'
<?xml version="1.0" encoding="UTF-8"?>
<response>
<lst name="responseHeader"><int name="status">0</int><int name="QTime">13</int><lst name="params"><str name="shards">127.0.0.1:8093/solr/my_index</str><str name="q">text:saisa</str><str name="fq">(_yz_node:riak@127.0.0.1 AND ((_yz_pn:62 AND (_yz_fpn:62)) OR _yz_pn:61 OR _yz_pn:58 OR _yz_pn:55 OR _yz_pn:52 OR _yz_pn:49 OR _yz_pn:46 OR _yz_pn:43 OR _yz_pn:40 OR _yz_pn:37 OR _yz_pn:34 OR _yz_pn:31 OR _yz_pn:28 OR _yz_pn:25 OR _yz_pn:22 OR _yz_pn:19 OR _yz_pn:16 OR _yz_pn:13 OR _yz_pn:10 OR _yz_pn:7 OR _yz_pn:4 OR _yz_pn:1))</str></lst></lst><result name="response" numFound="4" start="0" maxScore="0.714438"><doc><str name="_yz_id">my_type_my_bucket_name_40_2bc30rswtUNBw8YGIg9NWb</str><str name="_yz_rk">name</str><str name="_yz_rt">my_type</str><str name="_yz_rb">my_bucket</str></doc><doc><str name="_yz_id">my_type_my_bucket_name_40_2aIAVqcBF1ofLErIZ3njhM</str><str name="_yz_rk">name</str><str name="_yz_rt">my_type</str><str name="_yz_rb">my_bucket</str></doc><doc><str name="_yz_id">my_type_my_bucket_name_40_6b1S6KjPezKTQuWLzc86rR</str><str name="_yz_rk">name</str><str name="_yz_rt">my_type</str><str name="_yz_rb">my_bucket</str></doc><doc><str name="_yz_id">my_type_my_bucket_name_40_61ulEKXw5DmxJBlyIE9lPr</str><str name="_yz_rk">name</str><str name="_yz_rt">my_type</str><str name="_yz_rb">my_bucket</str></doc></result>
</response>

日本語だとどうなるのか

[vagrant@localhost riak]$ curl -H 'content-type: text/plain' \
> -X PUT 'http://localhost:8098/types/my_type/buckets/my_bucket/keys/name1’ \
> -d "彼女がほしい"
[vagrant@localhost riak]$ curl -H 'content-type: text/plain' \
> -X PUT 'http://localhost:8098/types/my_type/buckets/my_bucket/keys/name2’ \
> -d "アドベントカレンダー書いてる場合じゃねぇ"
[vagrant@localhost riak]$ curl -H 'content-type: text/plain' \
> -X PUT 'http://localhost:8098/types/my_type/buckets/my_bucket/keys/name3' \
> -d "どこに行けば彼女落ちてますか"

[vagrant@localhost riak]$ curl 'http://localhost:8098/search/my_index?q=text:彼女'
<?xml version="1.0" encoding="UTF-8"?>
<response>
<lst name="responseHeader"><int name="status">0</int><int name="QTime">364</int><lst name="params"><str name="shards">127.0.0.1:8093/solr/my_index</str><str name="q">text:彼女</str><str name="fq">(_yz_node:riak@127.0.0.1 AND (_yz_pn:64 OR (_yz_pn:61 AND (_yz_fpn:61)) OR _yz_pn:60 OR _yz_pn:57 OR _yz_pn:54 OR _yz_pn:51 OR _yz_pn:48 OR _yz_pn:45 OR _yz_pn:42 OR _yz_pn:39 OR _yz_pn:36 OR _yz_pn:33 OR _yz_pn:30 OR _yz_pn:27 OR _yz_pn:24 OR _yz_pn:21 OR _yz_pn:18 OR _yz_pn:15 OR _yz_pn:12 OR _yz_pn:9 OR _yz_pn:6 OR _yz_pn:3))</str></lst></lst><result name="response" numFound="2" start="0" maxScore="0.66360974"><doc><str name="_yz_id">my_type_my_bucket_name1_64</str><str name="_yz_rk">name1</str><str name="_yz_rt">my_type</str><str name="_yz_rb">my_bucket</str></doc><doc><str name="_yz_id">my_type_my_bucket_name3_42</str><str name="_yz_rk">name3</str><str name="_yz_rt">my_type</str><str name="_yz_rb">my_bucket</str></doc></result>
</response>

numFoundはしっかり2になっている。
Solrすげぇ!

まとめ

これまでのRiak Searchは、日本語の検索ができない、インデックスの作成が遅いなどの欠点があったようだ。
しかし来る2.0では、Solrの機能を取り込んだ"実用できる"検索機能が期待できる。
しかもYokozunaの本領は、運用フェーズだ。
データもインデックスも、運用を簡単にしたまま、高度で安定した機能を提供する。
これこそがRiakとSolrを組み合わせたことによる恩恵といえる。

ちなみに、Bashoのドキュメントサイトの検索機能はYokozunaで作られているらしい。

参考

http://www.youtube.com/watch?v=nQL2SnqV7Pk
https://github.com/basho/yokozuna
https://github.com/basho/yokozuna/blob/develop/docs/INSTALL.md
http://www.slideshare.net/takashisogabe/riak-meetup2-iijbeta2
https://speakerdeck.com/basho/yokozuna-ricon

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
24
Help us understand the problem. What are the problem?