elasticsearchでは、fuzzy queryの機能を用いることで、いわゆる曖昧検索を実現することができます。これにより、検索クエリ文字列のタイプミス(挿入、欠落、置換等)を吸収することが可能です。
簡単なサンプル
例えば、"title" というフィールドに、以下のような値が登録されているとします。tokenizerには一般的なkuromoji_tokenizerを使用しているとします。
"title" : "ベンチャー企業就職のススメ"
これに以下のようなクエリを投げると、当然ですがヒットします。
"query": {
"match": {
"title": {
"query": "ベンチャー"
}
}
}
fuzzy queryを使うには、"fuzziness" を設定するだけです。
"query": {
"match": {
"title": {
"query": "ベそチャー",
"fuzziness" : "AUTO"
}
}
}
これなら、クエリがべチャーでもベンちャーでもヒットさせることができます。
fuzzinessの設定
上のsampleではfuzzinessが"AUTO"に設定されていますが、これはelasticsearch側で、置換・挿入・欠落を許容する文字数を自動で判断してくれる設定です。0 〜 2 の値を明示的に設定することで、許容可能な範囲はある程度調節可能です。
"fuzziness" : 0 # 1~2文字向け
"fuzziness" : 1 # 3~5文字向け
"fuzziness" : 2 # 6文字以上向け
この値次第では、例えば モブチャー でも、チャー でも "ベンチャー"にヒットするというような極端な設定にすることも可能です。
注意点
注意すべき点としては、まずスコアリングに関してです。例えば、"ベンチャー"という文字列に対して、完全一致の"ベンチャー"でヒットさせても、一文字違いの"ベそチャー"でヒットさせても、両者にScoreの違いは生まれないということです。また、なんらかの想定しない挙動になることが十分考えられるので、サジェスト等他の手段を用いることを公式でも薦めています。
一見便利そうな機能ですが、運用する場合には、十分な注意が必要そうです。
おまけ(Railsでのサンプル)
以下は、自分がRailsでサンプル作った時の検索メソッド(の一部)です。
Article.__elasticsearch__.search(
query: {
bool: {
should: [
{
match: {
title: { query: query, operator: 'or', analyzer: 'search_analyzer', fuzziness: 'AUTO'}
}
}
]
}
}
).records