1:ElasticSearch的查询权重
每个文档与查询的相关度,在全文搜索引擎中不仅需要找到匹配的文档,还需根据它们相关度的高低进行排序。
根据全文相关的公式或 相似算法(similarity algorithms) 会将多个因素合并起来,为每个文档生成一个相关度评分 _score 。_score 在查询结果中有显示
1:相关度评分理论
Lucene(或 Elasticsearch)使用 bool(bool model) 查找匹配文档时,会用一个名为 实用评分函数的公式来计算相关度。这个公式借鉴了 词频/逆向文档频率 和 向量空间模型,同时也加入了一些现代的新特性,如协调因子(coordination factor),字段长度归一化(field length normalization),以及词或查询语句权重提升。
1.1:bool模型
bool 查询可以接受 must 、 must_not 和 should 参数下的多个查询语句,就是and,or,not的意思
下面展示一些 内联代码片
。
{
"bool" : {
"must" : [],
"should" : [],
"must_not" : [],
}
}
1.2:词频
也就是查询值在一个字段中出现的次数。当然也可以禁用词频统计: “index_options”: “docs”
"match": {
"title": {
"query": "quick brown fox",
"index_options": "docs"
} }
1.3:字段长度归一值
字段长度归一值就是查询值在结果中所占长度的比例。占的越多值越大
对于 not_analyzed 字符串字段的归一值默认是禁用的,而对于 analyzed 字段也可以通过修改字段映射禁用归一值:禁用"norms": { “enabled”: false }
"match": {
"title": {
"query": "quick brown fox",
"index_options": "docs" ,
"norms": { "enabled": false }
} }
2:查询时提升相关度
2.1:boost权重
我们可以用boost 参数设置不同字段配置查询时的权重。
1:提升权重
给boost参数不同的值,比如1,5,10
"match": {
"title": {
"query": "quick brown fox",
"boost": 2 //使用boost权重设置为2,不设置的默认是1
} }
2:对多索引提升权重
当在多个索引中搜索时,可以使用参数 indices_boost 来提升整个索引的权重
get index */search{
"indices_boost": {
"index1": 3,
"index2": 2
}
"query":{}
}
2.2:词频统计配置
当我们不关心检索词频率TF对搜索结果排序的影响时,可以使用constant_score将查询语句query或者过滤语句filter包装起来。我们仍然可以用boost给与权重
当然也可以禁用词频统计: “index_options”: “docs”
{
"query":{
"bool":{
"should": [
{ "constant_score": {
"boost":2,
"query": { "match": { "description": "wifi" }} }},
{ "constant_score": {
"query": { "match": { "description": "garden" }} }},
{ "constant_score": {
"query": { "match": { "description": "pool" }} }}
]
}
}
}
2.3:查询结果评分修改:function_score
es提供了一些函数允许我们对查询的结果score评分进行修改,function_score 查询将查询query和函数function包括在内。在搜索时,可以将 function_score 查询与 field_value_factor 结合使用
field_value_factor :配置字段,最终的查询的score会由function_score 查询体的结果值通过field_value_factor配置字段的值进行协调。多用于点赞排名等数据。最终值:new_score=old_score*field_value_factor
GET /blogposts/post/_search
{
"query": {
"function_score": {
"query": { //function_scored的查询体
"multi_match": {
"query": "popularity",
"fields": [ "title", "content" ]
}
},
"functions": [ //function_score的functions函数
{"random_score": {}}, //functions函数的参数1:随机评分
{"gauss": { //functions函数的参数2:gauss中心化展示
"age": {
"origin": "2",
"scale": "1"
}
}
],
"field_value_factor": { //function_score参数1
"field": "votes" //该字段必须是integer等数值类型的数据,常用于点赞数等字段评分
},
"boost_mode": "sum", //function_score参数2
"max_boost": 1.5 //function_score参数3
}
}
}
1:field_value_factor参数解释
field:提取该字段的值乘以query的查询score评分=最终结果,相等于我们给每个查询的结果乘了值的系数
modifier :为了让最终结果减少field值系数的影响。
missing:如果文档没有该字段,则使用该值
factor:对于field字段值的均衡使用后new_score = old_score * log(1 + factor * field-value)
"field_value_factor": {
"field": "interger field" , //该字段必须是integer等数值类型的数据,常用于点赞数等字段评分
"modifier ":"none ", //none (默认状态)、 log 、 log1p 、 log2p 、 ln 、 ln1p 、 ln2p 、 square 、 sqrt 以及 reciprocal
"missing": 1,
"factor": 1
}
2:max_boost最大值限制
限制field_value_factor 的最大值,只会对函数的最大值有用,不会对不在函数内的查询构成作用
3:随机评分制:random_score
当_score评分结果一致时保证每次的展示结果都一致。 通过random_score设置值
"functions": [
{
"random_score": {
"seed": "the users session id" //常用用户id等保证每个人的结果一致
}
}
]
4:查询结果中心化:gauss
为了保证查询结果是我们想要的,我们可以设定距离,价格等为中心查询某一范围的值。让更合适的值靠近我们的展示。比如美团的展示(以价格,距离排序展示)
"functions": [
{"gauss": {
"age": { //以哪个字段的值进行计算
"origin": "2", //该字段的中心值
"offset": "", //以origin左右偏移多少为中心 :origin±offset 该范围内是1.0评分
"scale": "1" //偏出origin±offset到scale值内的评分默认是origin±offset评分值的一半0.5
}
}"weight ":2} //该函数的权重系数
]
3:相似度算法
在设置索引的mapping时为字段配置属性
“similarity”: “BM25”
2:实战验证
2.1:插入数据
2.2:验证