概要
SEO対策という言葉があるように、Googleの検索結果は単なる文字列の一致率ではなくホームページ自体にスコアが付けられており、それを元に検索の順位が決まります。
今回はElasticsearchでそのようなスコア順に並べる方法を説明します。
環境
- Elasticsearch 5.0.0
データの用意
同じ名前のmy site
というサイトを用意します。そしてそれぞれのスコアをs
で設定しています。
curl -s -XPOST localhost:9200/my_index/my_type/_bulk -d ' {"index": {"_id": "1"}} {"title": "my site", "body": "Bad site", "s": 1} {"index": {"_id": "2"}} {"title": "my site", "body": "Normal site", "s": 10} {"index": {"_id": "3"}} {"title": "my site", "body": "Good site", "s": 100} '
通常の文字列一致検索
通常のクエリだと
$ curl -s -XGET localhost:9200/my_index/my_type/_search?pretty -d ' { "query": { "match": { "title": "my site" } } }'
結果
{ "took" : 6, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "failed" : 0 }, "hits" : { "total" : 3, "max_score" : 0.51623213, "hits" : [ { "_index" : "my_index", "_type" : "my_type", "_id" : "2", "_score" : 0.51623213, "_source" : { "title" : "my site", "body" : "Normal site", "s" : 10 } }, { "_index" : "my_index", "_type" : "my_type", "_id" : "1", "_score" : 0.51623213, "_source" : { "title" : "my site", "body" : "Bad site", "s" : 1 } }, { "_index" : "my_index", "_type" : "my_type", "_id" : "3", "_score" : 0.51623213, "_source" : { "title" : "my site", "body" : "Good site", "s" : 100 } } ] } }
となります。
サイト | スコア |
---|---|
Good site | 0.51623213 |
Normal site | 0.51623213 |
Bad site | 0.51623213 |
どれもスコアが同じ0.51623213
なので順番は保証されません。
重み付けした検索
Function Score Query
を使います。パラメータを説明すると
パラメータ | 役割 |
---|---|
field_value_factor | 特定のフィールドによってスコアを上げる |
field | スコアに反映させたいフィールド |
modifier | スコアの計算方法。デフォルトはnone らしいですが試してみると掛け算されました |
missing | フィールドが無いときのデフォルト値 |
ではクエリを実行します。
$ curl -s -XGET localhost:9200/my_index/my_type/_search?pretty -d ' { "query": { "function_score": { "query": { "match": { "title": "my site" } }, "field_value_factor": { "field": "s", "modifier": "log1p", "missing": 1 } } } }'
結果
{ "took" : 5, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "failed" : 0 }, "hits" : { "total" : 3, "max_score" : 1.0346951, "hits" : [ { "_index" : "my_index", "_type" : "my_type", "_id" : "3", "_score" : 1.0346951, "_source" : { "title" : "my site", "body" : "Good site", "s" : 100 } }, { "_index" : "my_index", "_type" : "my_type", "_id" : "2", "_score" : 0.53760034, "_source" : { "title" : "my site", "body" : "Normal site", "s" : 10 } }, { "_index" : "my_index", "_type" : "my_type", "_id" : "1", "_score" : 0.15540136, "_source" : { "title" : "my site", "body" : "Bad site", "s" : 1 } } ] } }
※今回はスコア計算にlog1p
を使いましたが、この辺は実際に試してみてから調整する必要があります。
サイト | スコア |
---|---|
Good site | 1.0346951 |
Normal site | 0.53760034 |
Bad site | 0.15540136 |
ちゃんとスコアを元に順位をつけることができました。