UGA Boxxx

つぶやきの延長のつもりで、知ったこと思ったこと書いてます

【Elasticsearch】Multi-match queryを使ってみる

Elasticsearchをつかった検索で、複数のフィールドを検索対象とするクエリを発行したい、かつ、完全一致する場合はそのdocを通常の2倍のスコアにしたい

このとき、ESのMulti-matchクエリを使うことを検討してみた

www.elastic.co

基本的な使い方

this is a testというキーワードをsubjectmessageフィールドに対して検索する場合、次のように記述するだけ

GET /_search
{
  "query": {
    "multi_match" : {
      "query":    "this is a test", 
      "fields": [ "subject", "message" ] 
    }
  }
}

first_namelast_nameのような部分一致するものは*でまとめることもできる

GET /_search
{
  "query": {
    "multi_match" : {
      "query":    "Will Smith",
      "fields": [ "title", "*_name" ] 
    }
  }
}

ブーストする

このクエリの面白いところとして、個々のフィールドをキャレット(^)表記でブーストすることができる

例えば、this is a testというキーワードをsubjectmessageフィールドに対して検索する場合で、さらにsubjectとマッチするdocのスコアを2倍にしたい場合、次のようにすることができる

GET /_search
{
  "query": {
    "multi_match" : {
      "query":    "this is a test", 
      "fields": [ "subject^2", "message" ] 
    }
  }
}

やりたかったこと

やりたかったことは複数のフィールドを検索対象にした検索と完全一致する場合はスコアを2倍にしたいことなので、完全一致と部分一致でフィールドを書き分けられれば実現できそう

結論、これを実現するには以下のように記述するのがよさそう

GET /_search
{
  "query": {
    "multi_match" : {
      "query": "this is a test", 
      "fields": [ 
          "subject.keyword^2",
          "message.keyword^2",
          "subject",
          "message"
        ] 
    }
  }
}

Elasticsearchではフィールドのタイプをtext型にすると、自動的にkeyword型もつくってくれて、filed名.keywordで利用することができる

これにより、部分一致と完全一致のフィールドを分けて使うことができ、完全一致だけブーストさせるということができた