Elastic Search の index(table) を作成して部分 { 一致, 不一致 } 検索をする
kaede
Posted on July 29, 2022
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
Posted on July 29, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.