ElasticSearch-常用搜索
Posted 肉蟹宝
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ElasticSearch-常用搜索相关的知识,希望对你有一定的参考价值。
全文检索查询
使用场景
全文检索的基本流程如下:
- 对用户搜索的内容做分词,得到词条
- 根据词条去倒排索引库中匹配,得到文档id
- 根据文档id找到文档,把所有匹配结果以并集或交集返回给用户
比较常见的场景包括:
- 商城的输入框搜索
- 百度的输入框搜索
DSL语句
常见的全文检索查询包括:
- match查询:单字段查询
- multi_match查询:多字段查询,任意一个字段符合条件就算符合查询条件
match查询
#搜索单字段 GET /indexName/_search "query": "match": "字段名称":"TEXT", "operator":"or and" #搜索分词时选择关键字的关系为or 或者 and #搜索全部 GET /indexName/_serach "query": "match_all":
multi_match查询
GET /indexName/_search "query": "mutil_match": "query":"TEXT", "field":["FIELD1","FIELD2"]
精确查询
使用场景
精确查询一般是查找keyword、数值、日期、Boolean等类型字段,所以不会对搜索条件分词。常见的有:
- term:根据词条精确值查询 equals =
- range:根据值的范围查询 >= , <=, between and
DSL语句
term查询
// term查询 GET /indexName/_search "query": "term": "FIELD": "value": "VALUE"
range查询
// range查询 GET /indexName/_search "query": "range": "FIELD": "gte": 10, // 这里的gte代表大于等于,gt则代表大于 "lte": 20 // lte代表小于等于,lt则代表小于
地理坐标查询
使用场景
所谓的地理坐标查询,就是根据经纬度查询
常见的使用场景包括:
- 携程:搜索附近的酒店
- 滴滴:搜索附近的出租车
- 微信:搜索附近的人
DSL语句
geo_bounding_box查询
矩形范围查询,也就是geo_bounding_box查询,查询会落在某个矩形范围内的所有文档:
查询时,需指定左上,右下两个坐标
语法如下:
# 地理位置搜索 GET hotel/_search "query": "geo_bounding_box": "location": "top_left": "lat":31.1, "lon":121.5 , "bottom_right": "lat":30.9, "lon":121.7
geo_distance查询
附近查询,也叫距离查询:查询到指定中心点小于某个距离的所有文档
语法如下:
GET hotel/_search "query": "geo_distance": "distance":"15km", "location":"31.21,121.5"
复合查询-布尔查询
使用场景
布尔查询是一个或多个查询子句的组合,每一个子句就是一个子查询。子查询的组合方式有:
- must:必须匹配每个子查询,类似“与”,must的条件参与算分的
- should:选择性匹配子查询,类似“或”
- must_not:必须不匹配,不参与算分,类似“非”
- filter:效果和must一样,都是and。必须匹配,filter的条件不参与算分
DSL语句
GET /hotel/_search "query": "bool": "must": [ "term": "city": "上海" ], "should": [ "term": "brand": "皇冠假日" , "term": "brand": "华美达" ], "must_not": [ "range": "price": "lte": 500 ], "filter": [ "range": "score": "gte": 45 ]
复合查询-算分函数查询
使用场景
ElasticSearch会根据词条和文档的相关度打分,算法有两种:
- TF-IDF算法
- BM25算法,ES5.1版本后采用的算法
相关场景:百度搜索打广告的优先展示
DSL语句
function score 查询包含四部分内容:
- 原始查询条件:query部分,基于这个条件搜索文档,并且基于BM25算法给文档打分,原始算分
- 过滤条件:filter部分,符合该条件的文档才会重新算分
- 算分函数:符合filter条件的文档要根据这个函数做运算,得到的函数算法,有四种函数:
-
- weight:函数结果是常量
- filed_value_factor:以文档中某个字段值作为函数结果
- random_score:以随机数作为函数结果
- script_score:自定义算分函数算法
- 运算模式:算分函数的结果,原始查询的相关性算分,两者之间的运算关系包括:
-
- multiply:相乘
- replace:用function score替换query score
- 其他,例如:sum、avg、max、min
function score的运行流程如下:
- 根据原始条件查询搜索文档,并且计算相关性算分,称为原始算分
- 根据过滤条件,过滤文档
- 符合过滤条件的文档,基于算分函数运算,得到函数算分
- 将原始算分和函数算分基于运算模式做运算,得到最终结果,作为相关性算分
语法如下:
# 需求: 查询如家酒店, 对于深圳的如家进行+10分 GET hotel/_search "query": "function_score": "query": "match": "all": "如家" , "functions": [ "filter": "term": "city": "深圳" , "weight": 10 ], "boost_mode": "sum"
搜索结果处理
排序
elasticsearch默认是根据相关性算分来排序,但是也支持自定义方式对搜索结果排序,可以排序的字段类型有:keyword类型、数值类型、地理坐标类型、日期类型等
普通字段排序
keyword、数值、日期类型的排序的语法基本一致
语法如下
GET /indexName/_search "query": "match_all": , "sort": [ "FIELD": "desc" // 排序字段、排序方式ASC、DESC ]
排序条件是一个数组,按照声明的顺序,当第一个条件相等时,再按照第二个条件排序
地理坐标排序
语法如下
GET /indexName/_search "query": "match_all": , "sort": [ "_geo_distance" : "FIELD" : "纬度,经度", // 文档中geo_point类型的字段名、目标坐标点 "order" : "asc", // 排序方式 "unit" : "km" // 排序的距离单位 ]
- 指定一个坐标,作为目标点
- 计算每一个文档中,必须是geo_point类型的坐标到目标点的距离是多少
- 根据距离排序
分页
elasticsearc默认情况下只返回top10的数据,而如果要查询更多数据就要修改分页参数,elasticsearch中·通过修改from、size参数来控制要返回的分页结果
- from:从第几个文档开始,从0开始的
- size:总共查询几个文档
语法如下:
# 查找如家酒店,查找离我最近的如家酒店, 分页 GET hotel/_search "query": "match": "name": "如家酒店" , "sort": [ "_geo_distance": "location": "39.76,116.33", "order": "asc", "unit": "km" ], "from": 1, "size": 2
高亮显示
对关键字高亮处理
语法如下
GET /hotel/_search "query": "match": "FIELD": "TEXT" // 查询条件,高亮一定要使用全文检索查询 , "highlight": "fields": // 指定要高亮的字段 "FIELD": "pre_tags": "<em>", // 用来标记高亮字段的前置标签 ,默认使用<em>标签 "post_tags": "</em>" // 用来标记高亮字段的后置标签
注意:
- 高亮是对关键字高亮,因此搜索条件必须带有关键字而不能是范围这样的查询
- 默认情况下,高亮的字段,必须与搜索的指定的字段一致,否则无法高亮
- 如果对非搜索字段高亮,则需要添加一个属性:required_filed_match=false
以上是关于ElasticSearch-常用搜索的主要内容,如果未能解决你的问题,请参考以下文章
lucene-查询query->TermQuery按词条搜索