简介
ES是一个基于Lucence构建的一个搜索服务, 它从搜索库搜索符合条件的索引数据。
Lucence不是一个完整的全文搜索引擎, 而是一个全文检索引擎架构, 提供了完整的查询引擎和索引引擎, 部分文本分析引擎. 开发人员可以通过Java语言将Lucence直接集成到应用程序中, 而Lucence非常复杂, 是的开发者自己开发搜索引擎非常困难, 而Elastic Search是一个已经写好了的搜索引擎, 可以直接使用.
全文搜索
计算机通过扫描文章中的每个词, 对每个词建立一个索引, 指明该词在文章中出现的次数和位置, 当用户查询时, 检索程序就根据事先建立的索引进行查找, 并将查找的结果反馈给用户的检索方式
倒排索引
该索引表中的每一项都包括一个属性值和具有一个该属性值得个记录的地址. 由于不是记录来确定属性值, 而是属性值来确定记录的位置, 从而成为倒排索引.
几种检索方式
-
query string search : 查询字符串搜索
-
query DSL : 特定领域的语言
-
query filter : 过滤查询
-
full-text search : 全文搜索
-
phrase search : 短语搜索
-
hightlight search : 高亮搜索
-
查询所有的文档
根据索引名创建搜索请求
SearchRequest searchrequest = new SearchRequest(“索引名”);
创建搜索资源构建对象
SearchSourceBuilder searchSourcebuilder = new SearchSourceBuilder();
创建全文搜索
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
searchRequest.source(searchSourceBuilder); -
分页查询
searchSourceBulider.from(0) 设置当前页页码, 从1开始
searchSourceBuilder.size(10) 设置每页显示条数
返回数据:
将构建查询放进请求中: searchSourceRequest.source(searchSourceBuilder);
获取请求的响应数据: SearchResponse searchResponse = client.search(searchRequest);
SearchHits hits = searchResponse.getHits();
long total = hits.getTotalHits(); //查询结果总条数
SearchHit[] searchHits = hits.getHits(); //查询结果
for(SearchHit hit : searchHits){
Map<String ,Object> map = his.getSourceAsMap(); 将每条数据存储到map集合中
String name = (String) map.get(“字段名”); //获取集合中的数据
// 可以将获取到的数据封装到对象中, 返回
} -
Term Query
精确查询, 搜索时整体匹配关键字, 不再将关键字分词
searchSourceBuilder.query(QueryBuilders.termQuery(“name”,“spring”))
参数1: 搜索字段 参数2: 搜索匹配值
搜索name值为: spring的数据 -
id精确查询
同上, 只不过根据id字段查询而已
List list = new ArrayList<>();
searchSourceBuilder.query(QueryBuilders.termQuery("_id",list)
依次搜索id字段等于上面集合中值的数据 -
match Query
全文搜索, 搜索前先将关键字分词, 在去索引库中搜索匹配项
参数: query: 搜索的关键字, 如果是英文关键字, 多个之间只用半角逗号隔开; 如果是中文关键字可以使用半角逗号隔开也可以不用.
operator: 其中有两个属性值: or 和 and , 当设置为or的时候, 多个关键词分词中匹配一个即可, 当设置为and时, 多个关键词分词中必须全部匹配
searchSourceBuilder.query(QueryBuilder.matchQuery(“description”,“spring开发”).operator(Operator.OR)) -
multi Query
可以依次匹配多个字段, 当有多个字段时拿关键字去多个Field中匹配, 如果是单项匹配, 在一个field中去匹配, 如果想多个字段中, 某个字段做重点搜索, 其他字段次之, 可以在重点字段提上字段权重(boost)
QueryBuilders.multiMatchQuery(“spring框架”,“name”,“discription”).minimunShouldMatch(“50%”);
multiMatchQueryBuilder.field(“name”,10), 将name的权重提升10倍 -
布尔查询
作用为: 将多个查询组合起来, 三个方法: must、should、must_not
must: 表示必须, 多个查询条件必须都满足
should: 表示或者, 多个查询只要有一个满足即可
must_not: 表示非, 不可以满足条件
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(multiMatchQueryBuilder);
boolQueryBuilder.must(termQueryBuilder);
searchSourceBuilder.query(boolQueryBuilder); -
过滤器
过滤是针对搜索结果进行过滤, 过滤器主要判断文档是否匹配, 不去计算和判断文档的匹配度得分, 所以过滤器性能比查询更高, 且方便缓存, 推荐使用过滤器其实现查询或者过滤器和查询共同使用.
boolQueryBuilder.filter(QueryBuilders.termQuery(“studymodel”,“201001”));
boolQueryBuilder.filter(QueryBuilders.rangeQuery(“price”).gte(40).lte(60));
过滤结果, 只得到studymodel = 201001 和 40 < price < 60 -
排序
可以在字段上添加一个或多个排序, 支持在keyword、date、float等类型,text类型上不允许添加排序。
searchSourceBuilder.sort(new FieldSortBuilder(“studymodel”).order(SortOrder.DES)); 降序
searchSourceBuilder.sort(new FieldSortBuilder(“price”).order(SortOrder.ASC)); 升序 -
高亮显示
高亮显示可以将搜索结果一个或多个字突出显示, 以便向用户显示关键字的位置
方式: 在搜索语句中添加highlight
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.preTags("");
highlightBuilder.postTags("");
highlightBuilder.fields().add(new HighlightBuilder.Field(“name”)); 添加高亮字段
searchSourceBuilder.highlighter(highlightBuilder);
关于节点
主节点: master节点主要用于集群的管理和索引比如新增节点,分片分配, 索引的新增和删除
数据节点: data节点保存了数据分片, 它负责索引和搜索此操作
客户端节点:
关于倒排索引
资料来源于: https://www.cnblogs.com/dreamroute/p/8484457.html
Posting List
ES中每个Field(field:领域, 可以理解为:字段)都建立了倒叙排序, Field中的元素都有个自己的位置数组(Posting List), 这个数据是一个int数组, 存储着ES中存储的文档中, 含有该term的文档ID.
格式例如: Name 领域中
| Term | Posting List |
| Mark | [1,2,3] | //表示ES库中文档ID为1/2/3的文档中含有的name=Mark的信息
Trem Dictionary
ES为了快速查找到指定的term, 将所有的term进行排序, 二分法查找term, 查找效率为logN, 类似字典查找, 此为: Term Dictionary .和传统的B-Tree的方式类似. 但是比B-Tree更快.
Term Index
B-Tree通过减少磁盘寻道次数来提高查询性能, ES也是采用相同的思路, 直接通过内存查找term, 不读磁盘, 但是如果term太多, term dictionary会很大, 放在内存不现实, 于是有了Term Index, 就像字典的索引页一样, 例如: A开头的有哪些term, 分别在那一页, term index中记录该term dictionary的位置, 查找到term dictionary后再通过term dictionary的文档id, 查找到目标文档, 可以理解为term index是一颗树.
这棵树不会包含所有的term, 它包含的是term的一些前缀. 通过term index可以快速定位到term dictionary的某个offset, 然后从这个位置再往后顺序查找.
所以term index不需要存下所有的term, 而是仅仅是他们的一些前缀与term Dictionary的block之间的映射关系, 在结合FST(Finite State Transducers)压缩技术, 将term index缓存到内存中, 从term index查到对应的term dictionary的block位置之后, 再去磁盘上找term, 大大减少了磁盘随机读的次数.
关于FST压缩技术, 尚未学习.
FST以字节的方式
压缩技巧
联合索引
以上说的是单个Field的索引, 如果多个索引的联合查询, 排序索引如何满足快速查询的要求呢?
利用跳表(Skip list)是数据结构快速做"与"运算
或者利用上面的bitset按位做"与"运算,