Elasticsearch パーコレータ

Elasticsearch Percolator — ○○検知システム構築で使える、便利なパーコレータの仕組みと使い方

Miyuki Endo
Hello! Elasticsearch.

--

Percolator とは?

ろ過器。
その名の通り、雑多な情報の中から欲しい情報だけを拾い(あれば)通知する、といったことができるElasticsearchの機能です。ちょっと変わっているのが、「ドキュメントをさがす」のではなく、「条件(クエリ)をさがす」ところです。

このElasticsearchのPercolatorに関する公式ガイドは何度読んでもなかなか理解できなかったので(私だけかもしれませんが)、概要をまとめてみたいと思います。

〜 MEMO 〜
Elasticsearch 0.9 と1.0以降とでPercolatorの設計が変わったようです。
0.9では、”_percolator”という1つのINDEXの位置づけでしたが、1.0以降は、INDEXの中のTYPEの位置づけになりました。

仕組み

標準的な検索では、ドキュメントをINDEXし、条件を指定したクエリを発行して検索しますが、Elasticsearchのpercolatorは逆の考えです。
クエリをINDEXしておき、あるドキュメントを投げた時に、マッチするクエリが存在すればそのクエリ(実際にはINDEXされているpercolatorのID)がリストで返される仕組みです。

図にするとこんな感じでしょうか。

標準的な検索のイメージ

上図のように、”a and b”のドキュメントをさがす標準的な検索に対し、percolatorでは下図のように、DocumentAにマッチする登録済みのクエリ (“a and b”であるか : Query1、 “c or d”であるか : Query2、 “a and d”であるか : Query3)をさがします。

パーコレータのイメージ

実際に使ってみよう!

サンプルとしてはあまり面白くありませんが、会社HPのコンテンツを使うことにします…
簡単なパターンで、「サイト内のニュースに ”AR” に関する情報が入ったら通知してほしい」という仕組みを構築する場合のパーコレーターの設定をしてみます。

INDEX:kwsite
“AR”に関する情報:ドキュメントの”title”と”content”に「AR」というワードが含まれるコンテンツ
とする

percolator queryをINDEXしてみる

“kwsite” INDEX内に”p1”というIDでpercolator queryを作成します。

curl -XPUT 'localhost:9200/kwsite/.percolator/p1' -d '{
"query":{
"multi_match":{
"fields":["title","content"],
"query":"AR"
}
}
}'

以下のように返ってきて無事作成できました。

{“_index”:”kwsite”,”_type”:”.percolator”,”_id”:”p1",”_version”:1,”created”:true}

〜 MEMO 〜
percolator queryでは”has_child”などのクエリが使えないようです。詳しくはガイドをご確認ください。

ドキュメントを投げてみる

サイト内のお知らせ情報の1ドキュメントをGETで投げて、先程登録したpercolatorにマッチするか(AR関連のドキュメントかどうか)確認してみます。

○未インデックスのドキュメントを使う場合

curl -XGET 'localhost:9200/kwsite/news/_percolate?pretty' -d '{
"doc":{
"title":"セミナー「プラス+AR & ビーコン体験 2014」を開催します",
"content":"下記日時にて、セミナー「プラス+AR & ビーコン体験 2014」を開催いたします。 主な内容:2014年ARのトレンド、ビーコンの活用ソリューションのご紹介、新しいマルチARのご紹介 などを予定",
"url":"http://hp.knowledge-works.co.jp/2014/06/6655/",
"tags":["AR","スマートスクリーン","セミナー"],
"date":"2014-06-09"
}
}'

このサンプルではmapping定義をしていませんが、実際に使う際は必要に応じてAnalyzerなどの設定をしたType (サンプルの“news”の部分)を指定します。

結果は次の通りです。

{
“took” : 3,
“_shards” : {
“total” : 5,
“successful” : 5,
“failed” : 0
},
“total” : 1,
“matches” : [ {
“_index” : “kwsite”,
“_id” : “p1"
} ]
}

先程INDEXした”p1”が返ってきました。

○インデックス済みのドキュメントを使う場合

# まずはドキュメントをINDEX
curl -XPUT 'localhost:9200/kwsite/news/1' -d '{
"title":"セミナー「プラス+AR & ビーコン体験 2014」を開催します",
"content":"下記日時にて、セミナー「プラス+AR & ビーコン体験 2014」を開催いたします。主な内容:2014年ARのトレンド、ビーコンの活用ソリューションのご紹介、新しいマルチARのご紹介 などを予定",
"url":"http://hp.knowledge-works.co.jp/2014/06/6655/",
"tags":["AR","スマートスクリーン","セミナー"],
"date":"2014-06-09"
}'
# 上のINDEXをつかってpercolateをGET
curl -XGET 'localhost:9200/kwsite/news/1/_percolate?pretty'

これでも先程と同様の結果が返ってきました。

また、次のように複数のドキュメントを同時に投げることもできるので便利です。

○複数のドキュメントを一気に調べる場合

※その前にせっかくなのでpercolator queryをもう一つ、「”id”:”p2"、”tags”フィールドに”ウェブサービス”が含まれる」データを登録しておきます。

# percolator queryを追加
curl -XPUT 'localhost:9200/kwsite/.percolator/p2' -d '{
"query":{
"match":{
"tags":"ウェブサービス"
}
}
}'
# 3件のドキュメントを同時に調査
# !!①〜⑥は説明で使うために付けています。コマンド実行時は除去してください。
curl -XGET 'localhost:9200/kwsite/news/_mpercolate?pretty' -d '
{"percolate":{"index":"kwsite","type":"news","id":"1"}}
{}
{"percolate":{"index":"kwsite","type":"news"}}
{"doc":{"title":"動くカタログ!Combi ベビーカーはじめてBOOKでAR","content":"Combiのカタログ「ベビーカーはじめてBOOK」で、商品の使い方や特徴を伝えるツールとしてARを活用されています。 ミューアライブを起動してカタログにかざすと動画で詳細情報が提供されます。","url":"http://hp.knowledge-works.co.jp/2014/05/6635/","tags":["AR","mue Alive","カタログ","ベビーカー"]}}
{"percolate":{"index":"kwsite","type":"news"}}
{"doc":{"title":"【ナニツクル】今週のピックアップ!スマホアプリの満足度は?マーケティング活動にこんなアンケートがおすすめデス!","content":"「スマホアプリ」は驚異的に増え続け、今ではあらゆる企業が様々なスマホアプリを構築し運営しています...そんな声を聞いてより長く使い続けてもらえるアプリづくりに役立ててみませんか", "url":"http://hp.knowledge-works.co.jp/2014/04/6526/","tags":["ウェブサービス活用支援", "ナニツクル"]}}
'

複数のドキュメントを同時に投げる場合は、2行で1ドキュメントとなるように記述します。上のサンプルでは、①②が1つ目のドキュメント、③④が2つ目のドキュメント、⑤⑥が3つ目のドキュメントとなっています。
また、インデックス済みのドキュメントを使う場合は、「1行目にINDEX、TYPE、ID(①)、2行目は空(②)」を指定し、未インデックスのドキュメントを使う場合は、「1行目にINDEX、TYPE(③or⑤)、2行目にドキュメント内容(④or⑥)」を指定します。

これを実行すると次のような結果が返ってきます。

{
“responses” : [ {
“took” : 7,
“_shards” : {
“total” : 5,
“successful” : 5,
“failed” : 0
},
“total” : 1,
“matches” : [ {
“_index” : “kwsite”,
“_id” : “p1"
} ]
}, {
“took” : 7,
“_shards” : {
“total” : 5,
“successful” : 5,
“failed” : 0
},
“total” : 1,
“matches” : [ {
“_index” : “kwsite”,
“_id” : “p1"
} ]
}, {
“took” : 7,
“_shards” : {
“total” : 5,
“successful” : 5,
“failed” : 0
},
“total” : 1,
“matches” : [ {
“_index” : “kwsite”,
“_id” : “p2"
} ]
} ]
}

リストの1番目がリクエスト①②の結果、2番目がリクエスト③④の結果というフォーマットで返ってきます。
それで肝心の結果なのですが、1つ目と2つ目のニュース(ドキュメント)は”AR”に関する内容、3つ目のニュースは”ウェブサービス”に関する内容で、すばらしい!想定通りの結果が得られました。

percolator queryにquery以外の情報を登録して使いこなす

上記では簡単な使用方法を記載しましたが、実は、.percolatorを登録する際、 ”query”以外の情報も含めることができます。
例えば、次のように”priority”を登録しておくとします。

# percolator query に"priority"を設定
curl -XPUT 'localhost:9200/kwsite/.percolator/p3' -d '{
"query":{
"multi_match":{
"fields":["title","content"],
"query":"AR ビーコン"
}
},
"priority":"high"
}'

すると、ドキュメントを投げる際、以下のように”priority”が”high”のpercolator queryだけを対象にする、といったことができるのです。

curl -XGET 'localhost:9200/kwsite/news/_percolate?pretty' -d '{
"doc":{
"title":"セミナー「プラス+AR & ビーコン体験 2014」を開催します",
"content":"下記日時にて、セミナー「プラス+AR & ビーコン体験 2014」を開催いたします。 主な内容:2014年ARのトレンド、ビーコンの活用ソリューションのご紹介、新しいマルチARのご紹介 などを予定",
"url":"http://hp.knowledge-works.co.jp/2014/06/6655/",
"tags":["AR","スマートスクリーン","セミナー"]
},
"filter":{
"term":{
"priority":"high"
}
}
}'

結果は↓こんな感じ。先程登録した”priority”が”high”のもののみ返ってきました。

{
“took” : 2,
“_shards” : {
“total” : 5,
“successful” : 5,
“failed” : 0
},
“total” : 1,
“matches” : [ {
“_index” : “kwsite”,
“_id” : “p3"
} ]
}

どんなことができる?

では最後に、percolatorを使うとアプリケーションにどのような機能を構築できるか活用方法を考えてみたいと思います。

[ECサイト] 商品が入荷したらお知らせする
[NEWSサイト] あるキーワードを含むニュースを通知する(Googleアラートのような機能やキュレーションサイトのようなもの)
[SNS] 自社サービスに関する投稿チェック
[ログ系] システム関連のアラート、ユーザーアクションの監視
[口コミ、投稿系] よろしくない投稿のチェック、検知

まだまだいろいろな場面に活用できそうで、とても期待できます。

注意点を挙げるとすると、percolatorはメモリに保持されるため、そのあたり気をつける必要がありそうです。

--

--