DSL Query的分类
Elasticsearch提供了基于JSON的DSL(Domain Specific Language)来定义查询。常见的查询类型包括:
•查询所有:查询出所有数据,一般测试用。例如:match_all
•全文检索(full text)查询:利用分词器对用户输入内容分词,然后去倒排索引库中匹配。例如:
•match_query
•multi_match_query
•精确查询:根据精确词条值查找数据,一般是查找keyword、数值、日期、boolean等类型字段。例如:
•ids
•range
•term
•地理(geo)查询:根据经纬度查询。例如:
•geo_distance
•geo_bounding_box
•复合(compound)查询:复合查询可以将上述各种查询条件组合起来,合并查询条件。例如:
•bool
•function_score
查询DSL的基本语法是什么?
•GET /索引库名/_search
•{ “query”: { “查询类型”: { “FIELD”: “TEXT”}}}
查询所有
查询出所有数据
全文检索查询
match查询:全文检索查询的一种,会对用户输入内容分词,然后去倒排索引库检索,语法:
multi_match:与match查询类似,只不过允许同时查询多个字段,语法:
match和multi_match的区别是什么?
•match:根据一个字段查询
•multi_match:根据多个字段查询,参与查询字段越多,查询性能越差,一般不用它,直接查询复合字段即可 (索引映射里的 “copy”:”复合字段名”)
精确查询
精确查询一般是查找keyword、数值、日期、boolean等类型字段。所以不会对搜索条件分词。常见的有:
•term:根据词条精确值查询 •一般搜索keyword类型、数值类型、布尔类型、日期类型字段
•range:根据值的范围查询 (gte:>+,lte:<=,gt:>,lt:<)可以是数值、日期的范围
地理查询
•geo_bounding_box:查询geo_point值落在某个矩形范围的所有文档
•geo_distance:查询到指定中心点小于某个距离值的所有文档
复合查询
fuction score:算分函数查询,可以控制文档相关性算分,控制文档排名。
布尔查询
布尔查询是一个或多个查询子句的组合。子查询的组合方式有:
•must:必须匹配每个子查询,类似“与”贡献算分
•should:选择性匹配子查询,类似“或”贡献算分
•must_not:必须不匹配,不参与算分,类似“非”
•filter:必须匹配,不参与算分
elasticsearch中的相关性打分算法是什么?
•TF-IDF:在elasticsearch5.0之前,会随着词频增加而越来越大
•BM25:在elasticsearch5.0之后,会随着词频增加而增大,但增长曲线会趋于水平
搜索结果处理
elasticsearch支持对搜索结果排序,默认是根据相关度算分(_score)来排序。可以排序字段类型有:keyword类型、数值类型、地理坐标类型、日期类型等。
排序
elasticsearch支持对搜索结果排序,默认是根据相关度算分(_score)来排序。可以排序字段类型有:keyword类型、数值类型、地理坐标类型、日期类型等
普通排序
地理排序
分页
elasticsearch 默认情况下只返回top10的数据。而如果要查询更多数据就需要修改分页参数了。
elasticsearch中通过修改from、size参数来控制要返回的分页结果:
深度分页问题
如果搜索页数过深,或者结果集(from + size)越大,对内存和CPU的消耗也越高。因此ES设定结果集查询的上限是10000
解决方案
after search:
•优点:没有查询上限(单次查询的size不超过10000)
•缺点:只能向后逐页查询,不支持随机翻页
•场景:没有随机翻页需求的搜索,例如手机向下滚动翻页
scroll:
•优点:没有查询上限(单次查询的size不超过10000)
•缺点:会有额外内存消耗,并且搜索结果是非实时的
•场景:海量数据的获取和迁移。从ES7.1开始不推荐,建议用 after search方案。
高亮
高亮:就是在搜索结果中把搜索关键字突出显示。
原理是这样的:
•将搜索结果中的关键字用标签标记出来
•在页面中给标签添加css样式
RestClient查询文档
查询的基本步骤是:
1.创建SearchRequest对象
2.准备Request.source(),也就是DSL。
①QueryBuilders来构建查询条件
②传入Request.source() 的 query() 方法
3.发送请求,得到结果
解析结果(参考JSON结果,从外到内,逐层解析)
三大步
//创建请求对象
//发送请求
//最后调用解析响应的方法
