一、问题背景:
背景:语文老师反馈试题查询的结果不理想。 原因:正常应该靠前的题目,搜索得分比较靠后,没有在前几页显示出来。
一、Es默认的记分方式
使用Es时,查询出来的文档排序依据是_score,这个_score是如何计算的可以通过添加 “explain”: true 条件来查看。 它的计算原理是基于词频/逆向文档频率(TF/IDF),详情参考官方文档:相关度评分背后的理论
二、此种方式的弊端
Es默认的词频/逆向文档频率(TF/IDF)评分方式,对于出现次数较少的重要关键字提取效果不佳,可能会导致一些本想搜索出来的结果排在后面。
三、改进方式
1、使用邻近度来提高相关度
以should子句的形式添加更多特定查询。每个匹配了should子句的文档都会增加其相关度。另外,增大boost可以增大权重。
GET /_search
{
"from": 0,
"size": 10,
"timeout": "20s",
"query": {
"bool": {
"must": [
{
"match": {
"body": {
"query": "彩色的荒漠",
"operator": "OR",
"analyzer": "ik_max_word",
"prefix_length": 0,
"max_expansions": 50,
"minimum_should_match": "1",
"fuzzy_transpositions": true,
"lenient": false,
"zero_terms_query": "NONE",
"auto_generate_synonyms_phrase_query": true,
"boost": 1
}
}
}
],
"should": [
{
"match_phrase": {
"body": {
"query": "彩色的荒漠",
"slop": 3,
"boost": 2
}
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
},
"sort": [
{
"_score": {
"order": "desc"
}
},
{
"questionId": {
"order": "desc"
}
}
],
"track_total_hits": 2147483647
}
2、关键字functions和weight滤集提升权重分
可以为列表里的每个加强函数都指定一个filter,这样做的话,只有在文档满足此filter的要求,此filter的加强函数才会应用到文档上,也可以不指定filter,这样的话此加强函数就会应用到全部的文档上。一个文档可以一次满足多条加强函数和多个filter,如果一次满足多个,那么就会产生多个加强score。因此Es会先使用score_mode定义的方式来合并这些加强score们,得到一个总加强score,得到总加强score之后,才会再使用boost_mode定义的方式去和old_score做合并。
GET _search
{
"from": 0,
"size": 10,
"timeout": "20s",
"query": {
"function_score": {
"query": {
"bool": {
"must": [
{
"match": {
"body": {
"query": "彩色的荒漠",
"operator": "OR",
"analyzer": "ik_smart",
"prefix_length": 0,
"max_expansions": 50,
"minimum_should_match": 1,
"fuzzy_transpositions": true,
"lenient": false,
"zero_terms_query": "NONE",
"auto_generate_synonyms_phrase_query": true,
"boost": 1
}
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
},
"functions": [
{
"filter": {
"term": {
"body": "彩色"
}
},
"weight": 2
},
{
"filter": {
"term": {
"body": "的"
}
},
"weight": 2
},
{
"filter": {
"term": {
"body": "荒漠"
}
},
"weight": 2
}
],
"score_mode": "multiply",
"boost_mode": "multiply"
}
},
"sort": [
{
"_score": {
"order": "desc"
}
},
{
"questionId": {
"order": "desc"
}
}
],
"track_total_hits": 2147483647
}
四、Java代码
创建MatchPhraseQueryBuilder,具体参考:Java Elasticsearch Match Phrase 短语查询
|