why
柔軟に日本語を分解して検索できる Elastic Search を使って
複雑な条件でも自由自在に検索できるようになりたいから。
And, Or, Filter, これらをマスターしたい。
環境構築
アカウント作成してログインするだけなので簡単。
14 日しか使えないけど。
Elastic Search のアカウント作成、ログイン
新規登録すればクラウドトライアルで試しうちできるらしい。
なので登録してログインする
14 日間使えるらしい。
アプリ作成
NorthEast1 ( Japan ) を選択して
andOr というアプリ名で作成
クラウドプロバイダーが選択できるので、
ES はプラットフォームではないらしい。
作成されると、UserName と Pass が発行される
ローカルに作らなくても、もうこれでクエリを叩きまくって遊ぶことができる。
コンソールで基礎的な POST / GET を試す
Dev Tools にアクセスしてコンソールを開く
Java やプラグインは一切追加せずとも
左下の Management / Dev tools にアクセスすれば
Elastic Search を叩くクエリを書けて
かつ実行できるエディタが開く。
コンソールに新しい index を追加して同時にデータも追加する
チュートリアルに従って
POST /customer/_doc/1 { "name": "kaede" } name: kaede の json を POST で /customer/ の _doc/1 に送ると
POST /customer/_doc/1 { "name": "kaede" } customer という index (table 相当) が作成され
同時に
Document ID を 1 として name: kaede のデータも登録された。
2, 3 に john, dan, これらの名前のデータも登録した
{ "_index": "customer", "_id": "zAPpVIIB6_QPx1u8MGaH", "_version": 1, "result": "created", "_shards": { "total": 2, "successful": 2, "failed": 0 }, "_seq_no": 3, "_primary_term": 1 } なお、ID の指定をしないと UUID で作成される。
ID: 1 の kaede だけ GET する
GET /customer/_doc/1 customer インデックスの DocID 1 を GET すると
{ "_index": "customer", "_id": "1", "_version": 1, "_seq_no": 0, "_primary_term": 1, "found": true, "_source": { "name": "kaede" } } kaede が取れた。REST っぽいね。
HTTP Status もかかった時間もわかる。
これで基礎的な GET/POST は動作確認できた。
検索をする
indexName/_search
query
bool, must, match
これらを使うことで Elastic Search では検索ができる。
簡単な完全一致、完全不一致検索まで動作確認する。
index の中身を全て見る
GET /customer/_search indexName に _search をつけると
{ "took": 2, "timed_out": false, "_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 3, "relation": "eq" }, "max_score": 1, "hits": [ { "_index": "customer", "_id": "1", "_score": 1, "_source": { "name": "kaede" } }, { "_index": "customer", "_id": "2", "_score": 1, "_source": { "name": "john" } }, { "_index": "customer", "_id": "3", "_score": 1, "_source": { "name": "dan" } } ] } } index の中のデータが全て取れる。
これに query をつけることで、検索を実現できる。
名前で完全一致検索する
GET /customer/_search { "query": { "bool": { "must": [ { "match": { "name": "dan" } } ] } } } 公式ガイドを参考に query/bool/must/match で
項目: 値 で絞る。
query 事態を { } で囲わないと GET と紐付かないので注意。
{ "took": 3, "timed_out": false, "_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 1, "relation": "eq" }, "max_score": 0.9808291, "hits": [ { "_index": "customer", "_id": "3", "_score": 0.9808291, "_source": { "name": "dan" } } ] } } するとしっかり名前が dan のデータが絞り込めた。
大文字小文字を区別はしない。
ID は検索するフィールドではないのでこのやり方では絞り込めない。
なお、 dan はこれ以上区切られないので、da では引っかからないが
{ "match": { "name": "良" } } "hits": [ { "_index": "customer", "_id": "zAPpVIIB6_QPx1u8MGaH", "_score": 0.85443234, "_source": { "name": "良太郎" } } ] 良太郎 は漢字なので 良,太,郎 どれでも引っかかる。
名前で部分不一致検索する
逆に must_not を使うとそれを含まないデータを出せる
"query": { "bool": { "must_not": [ { "match": { "name": "dan" } } ] } } 先程のを must_not に変えると
"hits": [ { "_index": "customer", "_id": "1", "_score": 0, "_source": { "name": "kaede" } }, { "_index": "customer", "_id": "2", "_score": 0, "_source": { "name": "john" } } ] dan 以外が返ってくる。
まとめ
Elastic Search は Google でアカウント連携するだけで
簡単に実行環境を手に入れて勉強できる。
Mangement/Devtools にアクセスして
POST /{indexName}/_doc/{docId} { "{keyName}": "{valueName}" } これを打つだけでインデックス(テーブル)
と初期データが登録できる。
同じインデックスにこれを打つと追加できる。
GET /customer/_search これでインデックスの中身を全てみれる
GET /customer/_search { "query": { "bool": { "must": [ { "match": { "name": "dan" } } ] } } } こうやってクエリを渡すことで絞り込める。
dan は d や a では検索できないが
良太郎は どの文字でも検索できる。
以上。
次回
複雑な OR と AND をもつクエリも書きたい。
複数の key value を持つデータで、
所持金が 100k 以上または、職位が Manager 以上で、
クレジットカードのランクが Gold





Top comments (0)