做视频赚钱的网站有哪些,网站开发使用软件有哪些,从零开始做网站seo,成都有实力的seo团队Elasticsearch高阶查询 文章目录 Elasticsearch高阶查询相关性和相关性算分相关性 (Relevance)什么是TF-IDFBM25explain关键字Boosting如何通过Boost控制想要的文档排在前面#xff1f; 布尔查询#xff08;bool Query#xff09;查询语法语法格式 单字符串多字段查询三种场…Elasticsearch高阶查询 文章目录 Elasticsearch高阶查询相关性和相关性算分相关性 (Relevance)什么是TF-IDFBM25explain关键字Boosting如何通过Boost控制想要的文档排在前面 布尔查询bool Query查询语法语法格式 单字符串多字段查询三种场景最佳字段(Best Fields)多数字段(Most Fields)混合字段(Cross Field) 最佳字段查询(Dis Max Query)可以通过tie_breaker参数调整 混合字段 聚合查询聚合的分类数学运算如最大最小求和平均等Bucket aggregation类似于分组就是分桶的概念Pipeline Aggregation: 对其他的聚合结果进行二次聚合 相关性和相关性算分
搜索是用户和搜索引擎的对话用户关心的是搜索结果的相关性
是否可以找到所有相关的内容
有多少不相关的内容被返回了
文档的打分是否合理
结合业务需求平衡结果排名
如何衡量相关性:
Precision(查准率)-尽可能返回较少的无关文档Recall(查全率)-尽量返回较多的相关文档Ranking-是否能够按照相关度进行排序
相关性 (Relevance)
搜索的相关性算分描述了一个文档和查询语句匹配的程度。ES 会对每个匹配查询条件的结果进行 算分 _score。打分的本质是排序需要把最符合用户需求的文档排在前面。ES 5之前默认的相关性 算分采用TF-IDF现在采用BM 25。
什么是TF-IDF
TF-IDF (term frequency-inverse document frequency) 是一种用于信息检索与数据挖掘的常用加权 技术。
TF-IDF被公认为是信息检索领域最重要的发明除了在信息检索在文献分类和其他相关领 域有着非常广泛的应用。IDF的概念最早是剑桥大学的“斯巴克.琼斯”提出1972年一-“关键词特殊性的统计解释和它在文献检索中的应用”但是没有从理论上解 释IDF应该是用log(全部文档数/检索词出现过的文档总数)而不是其他函数也没有做进一 步的研究19701980年代萨尔顿和罗宾逊进行了进一步的证明和研究并用香农信息论做了证明现代搜索引擎对TF-IDF进行了大量细微的优化
Lucene中的TF-IDF评分公式
TF是词频Term Frequency
检索词在文档中出现的频率越高相关性也越高
IDF是逆向文本频率Inverse Document Frequency
每个检索词在索引中出现的频率频率越高相关性越低
比如java在100个文档中都有而多线程只有一个文档有那么java需要扫描100篇文档而多线程只需要扫描一篇所以java的相关性比多线程低。
java对于用户来说搜索java出现了100篇文档那么对用户搜索的相关性是低的。
字段长度归一值filed-length norm
字段的长度是多少?字段越短字段的权重越高。检索词出现在一个内容短的 title 要比同样的词出现在一个内容长的 content 字段权重更大。
说白了就是很长的content才找到那么一个搜索关键词那么相关性肯定低撒。
BM25
BM25 就是对 TF-IDF 算法的改进对于 TF-IDF 算法TF(t)部分的值越大整个公式返回的值就会越大。BM25 就针对这点进行来优化随着TF(t) 的逐步加大该算法的返回值会趋于一个数值。
explain关键字
在查询的时候加上explain:true可以返回相应的算分规则
POST hotel/_search
{explain: true, query: {match: {name: 北京}}
}返回具体的算分规则
_explanation : {value : 1.6035968,description : weight(name:北京 in 163) [PerFieldSimilarity], result of:,details : [{value : 1.6035968,description : score(freq2.0), computed as boost * idf * tf from:,details : [{value : 2.2,description : boost,details : [ ]},{value : 1.1731012,description : idf, computed as log(1 (N - n 0.5) / (n 0.5)) from:,details : [{value : 62,description : n, number of documents containing term,details : [ ]},{value : 201,description : N, total number of documents with field,details : [ ]}]},{value : 0.621351,description : tf, computed as freq / (freq k1 * (1 - b b * dl / avgdl)) from:,details : [{value : 2.0,description : freq, occurrences of term within document,details : [ ]},{value : 1.2,description : k1, term saturation parameter,details : [ ]},{value : 0.75,description : b, length normalization parameter,details : [ ]},{value : 9.0,description : dl, length of field,details : [ ]},{value : 8.815921,description : avgdl, average length of field,details : [ ]}]}]}]}Boosting
Boosting是控制相关度的一个手段。
参数Boost的含义
当Boost 1 时打分的权重相对性提升当 0 Boost 1时打分的权重相对性降低当Boost 0时贡献负分
如何通过Boost控制想要的文档排在前面
POST hotel/_search
{query: {match: {name: {query: 北京西直门,operator: and}}}
}如查询北京西直门的酒店
{_index : hotel2,_type : _doc,_id : 1765008760,_score : 13.104373,_source : {id : 1765008760,name : 如家酒店(北京西直门北京北站店),address : 西直门北大街49号,price : 356,score : 44,brand : 如家,city : 北京,business : 西直门/北京展览馆地区,location : 39.945106,116.353827,pic : https://m.tuniucdn.com/fb3/s1/2n9c/4CLwbCE9346jYn7nFsJTQXuBExTJ_w200_h200_c1_t0.jpg}},{_index : hotel2,_type : _doc,_id : 414168,_score : 12.663941,_source : {id : 414168,name : 7天连锁酒店(北京西直门店),address : 西城平安里西大街翠花街育幼胡同甲20-22号,price : 419,score : 37,brand : 7天酒店,city : 北京,business : 西单、金融街地区,location : 39.931338,116.364982,pic : https://m2.tuniucdn.com/filebroker/cdn/res/bc/66/bc666859edf4fc072a8006c66758058d_w200_h200_c1_t0.jpg}}可以看到如家评分在前面。
当我们将北京的条件boost相关性调低。
POST hotel/_search
{query: {boosting: {positive: {term: {name: {value: 西直门}}},negative: {term: {name: {value: 北京}}},negative_boost: 0.2}}
}{_index : hotel2,_type : _doc,_id : 414168,_score : 0.87095565,_source : {id : 414168,name : 7天连锁酒店(北京西直门店),address : 西城平安里西大街翠花街育幼胡同甲20-22号,price : 419,score : 37,brand : 7天酒店,city : 北京,business : 西单、金融街地区,location : 39.931338,116.364982,pic : https://m2.tuniucdn.com/filebroker/cdn/res/bc/66/bc666859edf4fc072a8006c66758058d_w200_h200_c1_t0.jpg}},{_index : hotel2,_type : _doc,_id : 1765008760,_score : 0.87095565,_source : {id : 1765008760,name : 如家酒店(北京西直门北京北站店),address : 西直门北大街49号,price : 356,score : 44,brand : 如家,city : 北京,business : 西直门/北京展览馆地区,location : 39.945106,116.353827,pic : https://m.tuniucdn.com/fb3/s1/2n9c/4CLwbCE9346jYn7nFsJTQXuBExTJ_w200_h200_c1_t0.jpg}}可以看到7天酒店的评分高了
这种业务场景在于**收费**的要排在前面即使它的相关性没那么高。
布尔查询bool Query
一个bool查询,是一个或者多个查询子句的组合总共包括4种子句其中2种会影响算分2种不影响算分。
must: 相当于必须匹配贡献算分should: 相当于or选择性匹配贡献算分must not: 相当于!必须不能匹配不贡献算分filter: 必须匹配不贡献算分
在Elasticsearch中有Query和 Filter两种不同的Context Query Context: 相关性算分 Filter Context: 不需要算分,可以利用Cache获得更好的性能
相关性并不只是全文本检索的专利也适用于yes|no 的子句匹配的子句越多相关性评分越高。如果多条查询子句被合并为一条复合查询语句比如 bool查询则每个查询子句计算得出的评分会被合并到总的相关性评分中。
查询语法
子查询可以任意顺序出现可以嵌套多个子查询如果bool查询中没有must条件should必须至少满足一个查询
语法格式
POST hotel/_search
{query: {bool: {must: [{},{},{}],should: [{},{},{}],must_not: [{},{},{}],filter: [{},{},{}]}}
}如查询北京市的如家酒店
POST hotel/_search
{query: {bool: {must: [{match: {brand: 如家}},{match: {city: 北京}}]}}
}查询北京市的如家酒店,并且不要国贸地区的
POST hotel/_search
{query: {bool: {must: [{match: {brand: 如家}},{match: {city: 北京}}],must_not: [{match: {business.keyword: 国贸地区}}]}}
}北京市的如家酒店,并且不要国贸地区的,并且价格在200到300之间并且价格不重要
POST hotel/_search
{query: {bool: {must: [{match: {brand: 如家}},{match: {city: 北京}}],must_not: [{match: {business.keyword: 国贸地区}}],filter: [{range: {price: {gte: 200,lte: 300}}}]}}
}北京市的如家酒店,并且不要国贸地区的,并且价格在200到300之间并且价格不重要,而且地址最好在莲花池的
POST hotel/_search
{query: {bool: {must: [{match: {brand: 如家}},{match: {city: 北京}}],must_not: [{match: {business.keyword: 国贸地区}}],filter: [{range: {price: {gte: 200,lte: 300}}}],should: [{match: {address: 莲花池}}]}}
}单字符串多字段查询
三种场景
最佳字段(Best Fields)
当字段之间相互竞争又相互关联。例如对于博客的 title和 body这样的字段评分来自最匹配字段
多数字段(Most Fields)
处理英文内容时的一种常见的手段是在主字段( English Analyzer)抽取词干加入同义词以匹配更多的文档。相同的文本加入子字段 (Standard Analyzer)以提供更加精确的匹配。其他字段作为匹配文档提高相关度的信号匹配字段越多则越好。
混合字段(Cross Field)
对于某些实体例如人名地址图书信息。需要在多个字段中确定信息单个字段只能作为整体的部分。希望在任何这些列出的字段中找到尽可能多的词
最佳字段查询(Dis Max Query)
将任何与任一查询匹配的文档作为结果返回采用字段上最匹配的评分最终评分返回
第一种写法:
POST hotel/_search
{query: {multi_match: {type: best_fields, query: 莲花,fields: [address,business],tie_breaker: 0.2}}
}type: best_fields默认
第二种写法
POST hotel/_search
{query: {dis_max: {tie_breaker: 0.7,queries: [{match: {address: 莲花}},{match: {business: 莲花}} ]}}
}可以通过tie_breaker参数调整
Tier Breaker是一个介于0-1之间的浮点数。0代表使用最佳匹配;1代表所有语句同等重要
获得最佳匹配语句的评分 score。将其他匹配语句的评分与tie breaker相乘对以上评分求和并规范化
混合字段
混合字段支持and符可以在多字段中精确查询每个字段。如四川成都在province中匹配四川在city字段中匹配成都
聚合查询
聚合主要用做统计分析功能常见的聚合操作有求和平均分组
语法
aggs: {aggs_name: { //自定义聚合查询的名字aggs_type : { //聚合的定义如求和还是平均什么的aggs_body},aggs : {} //子查询如某些先分组再平均的情况}
}
聚合的分类
数学运算如最大最小求和平均等
查询酒店价格最大最小和平均值,es默认会返回查询的数据结果使用size0可以不需要返回数据
POST hotel/_search
{size: 0,aggs: {max_price: {max: {field: price}},min_price : {min : {field: price}},avg_price : {avg: {field: price}}}
}{took : 3,timed_out : false,_shards : {total : 1,successful : 1,skipped : 0,failed : 0},hits : {total : {value : 201,relation : eq},max_score : null,hits : [ ]},aggregations : {max_price : {value : 3299.0},min_price : {value : 127.0},avg_price : {value : 660.6019900497513}}
}
利用stats类型计算所有的数学运算结果
POST hotel/_search
{size: 0,aggs: {stats_price: {stats: {field: price}}}
}{took : 0,timed_out : false,_shards : {total : 1,successful : 1,skipped : 0,failed : 0},hits : {total : {value : 201,relation : eq},max_score : null,hits : [ ]},aggregations : {stats_price : {count : 201,min : 127.0,max : 3299.0,avg : 660.6019900497513,sum : 132781.0}}
}去重查询 cardinality,主要是针对keyword进行去重如果是text类型不允许去重。
POST hotel/_search
{size: 0,aggs: {cardinate_city: {cardinality: {field: city}}}
}Bucket aggregation类似于分组就是分桶的概念
常见的分桶聚合
terms 需要字段支持fielddata keyword默认支持fielddatatext需要在Mapping中开启fielddata会按照分词后的结果进行分桶 数字类型 Range/Data RangeHistogram(直方图)/Data Histogram 支持嵌套也就在桶里再坐分桶
按照城市分组
POST hotel/_search
{aggs: {by_size: {terms: {field: city}}}
}按照价格区间分组
POST hotel/_search
{size: 0,aggs: {range_price: {range: {field: price,ranges: [{key: 小于200,to: 200},{key: 500以内,from: 200,to: 500},{key: 1000以内,from: 500,to: 1000},{key: 大于1000,from: 1000}]}}}
}aggregations : {range_price : {buckets : [{key : 小于200,to : 200.0,doc_count : 17},{key : 500以内,from : 200.0,to : 500.0,doc_count : 78},{key : 1000以内,from : 500.0,to : 1000.0,doc_count : 77},{key : 大于1000,from : 1000.0,doc_count : 29}]}}按照价格区间进行直方图查询
POST hotel/_search
{size: 0,aggs: {histogram_price: {histogram: {field: price,interval: 1000,extended_bounds: {min: 0,max: 3000}}}}
}嵌套查询如先按照城市进行分组再计算各城市酒店的平均价格
# 先按照城市进行分桶再求价格的平均值
POST hotel/_search
{size: 0,aggs: {bucket_city: {terms: {field: city},aggs: {avg_price: {avg: {field: price}}}}}
}Pipeline Aggregation: 对其他的聚合结果进行二次聚合
如求取各品牌下酒店平均价格的最小值
根据brand进行分桶求取分桶下price的平均值根据avg_price求最小值
POST hotel/_search
{size: 0,aggs: {terms_brand: {terms: {field: brand},aggs: {avg_price: {avg: {field: price}}}},min_price_by_brand : {min_bucket: {buckets_path: terms_brandavg_price}}}
}buckets_path下的 符号为路径符号意思是最小值通过terms_brand下的avg_price取