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值系数的影响。具体使用:
field_value_factor详解
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:验证

根据关键词命中词频计算权重 目前elasticsearch最常用的得分计算方式TF-IDF,原理的话就不赘述了,网上一抓一大把。这种利用词频与逆文档频率的计算方法的确很科学,应用也广泛(默认的得分计算方法)。但是对于一些使用检索的用户,有一种困惑,我某个字段命中多次为什么还排在后面呢?为什么不是我按照命中的词频来进行排序,再进一步优化的情况,就是某些字段的权重更高一些,这样更容易用户直观的理解。网上找了很多资料没找到,最终还是自己摸索出来了,下面用例子来快速描述场景吧。 需要实现的场景 拿新闻场景来
读者提问:ES权重排序有没有示列,参考参考? 刚好之前也稍微接触过,于是写了这篇文章,可以简单参考下。 在很多复杂的业务场景下,排序的规则会比较复杂,单一的降序,升序无法满足日常需求。不过 ES 中提供了给文档加权重的方式来排序,还是挺好用的。 首先初始化三条测试数据,方便查看效果: id: 1, title: "Java怎么学", type: 3, userId: 1, tags: [ "java" textContent: "我要学Java", status: 1 转载并且补充:https://mp.weixin.qq.com/s/0g86s-o7kgn8ZUxA3UBc0w 请看原文 读者提问:ES权重排序有没有示列,参考参考? 刚好之前也稍微接触过,于是写了这篇文章,可以简单参考下。 在很多复杂的业务场景下,排序的规则会比较复杂,单一的降序,升序无法满足日常需求。不过 ES 中提供了给文档加权重的方式来排序,还是挺好用的。 首先初始化三条测试数据,方便查看效果: POST score-test/_doc "id": 1, "title": curl -X GET 127.0.0.1:9200/articles/article/1 curl -X GET 127.0.0.1:9200/articles/article/1?_source=title,user_id curl -X GET 127.0.0.1:9200/articles/article/1?_source=false 查询所有 curl -X GET 127.0.0.1:9200/articles/
Elasticsearch搜索引擎Suggest查询建议-权重 重要:在加载数据库数据到es时,对索引字段“suggest_name”设置的值 进行修改 原:对索引字段直接进行设值,如:"suggest_name": "空调" 改:对索引字段进行编制,加入es的提供的权重判断,改为设值为: "suggest_name": { "input": "空调", "weight": 50 备注: 50 为 ,1个字在整个字符串中的占比,比如“空”就占 50%,“调”字类
根据文档ID curl -X GET 127.0.0.1:9200/articles/article/1 curl -X GET 127.0.0.1:9200/articles/article/1?_source=title,user_id curl -X GET 127.0.0.1:9200/articles/article/1?_source=false 查询所有 curl -X GET 127.0.0.1:9200/articles/article/_search?_sou