前言:
es的搜索有一些策略:
best-fields策略,主要是说将某一个field匹配尽可能多的关键词的doc优先返回回来(获取最佳匹配的field),另个可以通过tie_breaker来控制其他field的得分
most-fields策略,主要是说尽可能返回更多field匹配到某个关键词的doc,优先返回回来
在es多个shard背景下,搜索的结果会不太准确,
查询条件:
GET /forum/article/_search
{
"query": {
"bool": {
"should": [
{ "match": { "title": "java solution" }},
{ "match": { "content": "java solution" }}
]
}
}
}
计算每个document的relevance score:每个query的分数,乘以matched query数量,除以总query数量
算一下doc4的分数
{ “match”: { “title”: “java solution” }},针对doc4,是有一个分数的 { “match”: {
“content”: “java solution” }},针对doc4,也是有一个分数的所以是两个分数加起来,比如说,1.1 + 1.2 = 2.3 matched query数量 = 2 总query数量 = 2
2.3 * 2 / 2 = 2.3
算一下doc5的分数
{ “match”: { “title”: “java solution” }},针对doc5,是没有分数的
{ “match”: { “content”: “java solution” }},针对doc5,是有一个分数的所以说,只有一个query是有分数的,比如2.3
matched query数量 = 1
总query数量 = 22.3 * 1 / 2 = 1.15
doc5的分数 = 1.15 < doc4的分数 = 2.3
应该是某一个field(域)中匹配到了尽可能多的关键词,被排在前面;而不是尽可能多的field匹配到了少数的关键词,排在了前面
用dis_max
GET /forum/article/_search
{
"query": {
"dis_max": {
"queries": [
{ "match": { "title": "java solution" }},
{ "match": { "content": "java solution" }}
]
}
}
}
dis_max语法,直接取多个query中,**分数最高的那一个q**uery的分数即可
{ “match”: { “title”: “java solution” }},针对doc4,是有一个分数的,1.1
{ “match”: { “content”: “java solution” }},针对doc4,也是有一个分数的,1.2
取最大分数,1.2{ “match”: { “title”: “java solution” }},针对doc5,是没有分数的
{ “match”: { “content”: “java solution” }},针对doc5,是有一个分数的,2.3
取最大分数,2.3然后doc4的分数 = 1.2 < doc5的分数 = 2.3,所以doc5就可以排在更前面的地方,符合我们的需要
取最高分的话也不是很合理,有匹配情况比较好但是分不高还是会排在后面,所以介绍下tie_breaker
GET /forum/article/_search
{
"query": {
"dis_max": {
"queries": [
{ "match": { "title": "java beginner" }},
{ "match": { "body": "java beginner" }}
],
"tie_breaker": 0.3
}
}
}
tie_breaker(0~1之间,是个小数)
将其他query的分数 乘以tie_breaker 然后综合 最高分数的那个query的分数,一起进行计算
所以除了取最高分以外,还会考虑其他的query的分数
其他:boost:增加权重
minimum_should_match:“50%”控制搜索结果的精确度
另一种写法:
GET /forum/article/_search
{
"query": {
"multi_match": {
"query": "java solution",
"type": "best_fields",
"fields": [ "title^2", "content" ],
"tie_breaker": 0.3,
"minimum_should_match": "50%"
}
}
}
“fields”: [ “title^2”, “content” ], 搜索title、content,title权重*2