ElasticsearchのmatchクエリでANDとOR検索を実現する

Elasticsearchのmatchクエリを使うと、スペース区切りでのAND / OR検索が実行できます。

この記事の前提

この記事はElasticsearch 2.x系を想定しています。
それ以前orそれ以降のバージョンではクエリの仕様が異なる場合がありますのでご注意ください。

matchでのシンプルな検索クエリ

$ curl http://example.com/_search -d '{
  "query": {
    "match": {
      "title": "WordCamp Tokyo"
    }
  }
}'

この場合、titleというフィールドに対して、WordCampもしくはTokyoにマッチするデータがないかを検索します。

しかしこのままだと、WordCamp Tokyoの情報を調べたいのに「Tokyo Ramen Map」みたいなページも拾ってきちゃいます。なぜかといえば、matchクエリはデフォルトだと「WordCamp」か「Tokyo」どちらかにマッチすればOKというOR検索を実行するためです。

ということで、「WordCamp Tokyo」を検索したい場合は以下の様にANDクエリを作りましょう。

operatorを使ってAND検索

AND検索はoperatorというパラメータを追加することで実現できます。

$ curl http://example.com/_search -d '{
  "query": {
    "match": {
      "title": "WordCamp Tokyo",
      "operator": "and"
    }
  }
}'



複数のフィールドに対して検索を実行したい場合は、multi_match

matchクエリは1つのフィールドに対してのみ検索を実行します。ですので「タイトルと本文に対して検索を実行したい」という時は以下のようにmulti_matchクエリを使用します。

$ curl http://example.com/_search -d '{
  "query": {
    "multi_match": {
      "fields": [ "title", "content"],
      "query": "WordCamp Tokyo"
    }
  }
}'

fieldsというパラメータで検索対象のフィールドを指定し、queryパラメータで検索ワードを指定します。
基本的にはmultiクエリで利用できるパラメータは利用可能ですので、以下のようにAND検索を実行することも可能です。

$ curl http://example.com/_search -d '{
  "query": {
    "multi_match": {
      "fields": [ "title", "content"],
      "query": "WordCamp Tokyo",
      "operator": "and"
    }
  }
}'

おまけ:WordPressで検索を実行する場合

PHPでやるときは、配列でクエリを組み立ててから、json_encodeでJSONにするとお手軽です。

$url = 'http://example.com/_search';
$query = array(
  'query" => array(
    'multi_match' => array(
      'fields' => array( 'title', 'content' ),
      'query'  => 'WordCamp Tokyo',
      'operator' => 'and',
    ),
  ),
);
$body = array(
  'body' => json_encode( $query ),
);
$result = wp_remote_get( $url, $body );

そういえば

今週末はいよいよWordCamp Tokyo 2016ですね。

9/17 (土) タイムテーブル

カルタとか座談会とかもあるらしいですよ。

Follow me!