简介
keyword:
lucene
全文检索:顺序扫描法、全文检索(非结构化数据->带索引的结构化数据,一次索引创建,多次使用)
elastic search
solr
创建倒排索引 -> 定位到文档
分词、索引、类型、文档、分布式
参考链接:
https://blog.csdn.net/zhangdefeng2008/article/details/79591481 有对比
https://es.xiaoleilu.com/010_Intro/00_README.html 教程
https://blog.csdn.net/qq_15958689/article/details/79526784 分片概念
- 常用搜索引擎
- Lucene
Lucene是Apache发布的一个开放源代码的全文搜索引擎工具包,是一个全文检索引擎架构,提供了完整的创建索引和查询索引,以及部分文本分析的引擎
工作原理:
gateher data => Document(生成文档) => Index(做索引库) => Analyze(分词器)_打标签提高精准度
user <=> query <=> search index
全文搜索技术,绝大数是基于倒排索引来做;
词典+倒排表
Lucene是根据关键字来搜索的文本搜索工具,只能在某个网站内部搜索文本内容,不能跨站搜索
参考链接:https://blog.csdn.net/njpjsoftdev/article/details/54015485
- Elasticsearch
通过简单 restful API来隐藏Lucene的复杂性,从而让全文搜索变得简单
分布式以支持海量的数据
实时分析
分布式的实时文件存储,每个字段都被索引并可被搜索
正排索引:文档id到单词的关联关系 -> 文档中找字符串
倒排索引:单词到文档id的关联关系 -> 字符串找文档
倒排索引组成: 单词词典(B+树)_便于快速搜索到某个term 倒排列表(单词对应的文档集合)
ES存储的是一个JSON格式的文档,其中包含多个字段,每个字段会有自己的倒排索引
- solr
Solr索引的实现方法很简单,用Post向solr服务器发送一个描述Field及其内容的XML文档,Solr根据xml文档添加、删除、更新索引。然后对solr返回对xml,json等格式的查询结构进行解析,组织页面布局
对已有数据搜索时更快,当建立索引时,solr会产生io阻塞,查询性能差
随着数据量的增长,Solr的搜索效率会变得更低,而es没有明显变化
对比
solr利用zk进行分布式管理,而ES自带
solr支持更多的格式,es只支持json
处理实时搜索效率es更强
es建立索引快
Elastic Search
关键字
分词->倒排索引 (倒排索引一旦创建,不可更改,带来的好处)
压缩
搜索引擎原理:爬取内容 -> 进行分词 -> 就是建立反向索引
https://blog.csdn.net/u011635492/article/details/81023158 对于倒排过程比较细致,为什么比mysql B+树的检索速度快
- 专有名词:
索引(数据库) 、
类型(表)、
文档(行)、
Term(项-某列的具体值,也可能是Field下面的值分词之后的词元)、
Analyzer(分析器) + Tokenizer(分词器) + TokenFilters(词过滤器)
>全文搜索引擎对文档进行分析,首先通过Tokenizer得到token(切词处理),token通过token filter(停顿词过滤)获得Term > 小写分词器、空格分词器 模式分词器 合并词(Document Frequency,出现在所有文档的总数) > 将得到的词交给索引组件
Segment:
1、 lucene将一个大大逆向索引拆分成多个小段segment。每个segment本质上就是一个倒排索引
2、lucene维护一个文件commit point,记录当前所有可用的segment,当在commit point上进行搜索时,相当于在它下面的segment中进行搜索,汇总再返回给用户
3、 每个commit point都维护一个.del文件,文件内记录了在某个segment内某个文档已经被删除,但是在segment中依然可以被搜索到,不过在返回之前,会根据.del的内容过滤掉
文档的更新,类似。首先在.del文件中声明这个文档已经被删除,同时新的文档会被存到一个新的segment。 tranlog防止丢失后
Refresh: 近乎实时搜索,fsync操作确保写入磁盘成功, segment(先收集到indexing buffer)写入文件系统缓存(也可以被读取),未写入磁盘,在文件缓存中就可以读取segment
在es中,将缓存中的文档写入segment,并打开segment使之可以被搜索到过程叫做refresh(默认情况,分片的refresh时1次/s),
一条新写入的数据在refresh之前是搜索不到的
index.refresh_inteval:100s
倒排索引 建立 更新 删除
Shard (分片)最小级别的工作单元,保存索引中所有数据的一小部分,一个分片就是一个lucene实例,
主分片和复制分片
分布机制:https://blog.csdn.net/xiaocai9999/article/details/80561639 好理解
文档存储在分片中,并且在分片中被索引
索引
poems
类型
"poem":{
"properties":{
"title":{
"type":"keyword", //keyword类型不会分词,直接根据字符串内容建立反向索引
},
"author":{
"type":"keyword",
}
"dynasty":{
"type":"keyword",
},
"words":{
"type":"keyword",
},
"content":{
"type":"text", // text类型存入es的时候,会先分词,然后根据分词后的内容建立反向索引
},
}
}
文档
{
"title":"静夜思",
"author":"李白",
"dynasty":"唐",
"words":"20",
"content":"床前明月光,疑是地上霜,举头望明月,低头思故乡",
}
类型相当于表结构的描述,描述每个字段的类型
文档已json形式描述以一行数据
=> 存入elastic search
调用API
elastic 分布式原理
es集群可以包含多个索引(indices)
每个索引可以包含多个类型(types)
每个类型可以包含多个文档(documents)
每个文档包含多个字段(Fields)
elasticsearch会对数据进行切分,同时每一个分片会保存多个副本保证高可用性
master-slave
增删改查
建立索引和写入需要经过master,
数据的写入有一个简单的routing规则,可以route到集群中的任意节点(协调节点),所以数据写入压力是分散在整个集群的
Shard(分片):
一个lucene实例 一个节点可以包含多个分片
一个索引的所有数据时分布在所有主分片上的 主分片又分布在不同节点
主分片和复制分片,主分片写完,同步到副分片上,等所有分片写完才会成功
文档存在分片中(文档_id),并且在分片中被索引
分布式搜索
- 客户端发送一个search(搜索)请求, 请求给Node(随机轮询算法),这个node创建了一个长度为from+size的空优先级队列
- Node 转发这个搜索请求到索引中每个分片的原本或副本,每个分片在本地执行这个查询并且将结果到一个大小为from+size的有序本地优先队列里
- 每个分片返回document的ID和它优先队列里的所有document的排序值给协调节点Node,node把这些值合并到自己的优先队列里产生全局排序结果
elk系统: elasticsearch + logstash + kibana
实时计算模块:
https://blog.csdn.net/u010454030/article/details/75986072
Free Maker模版引擎
elasticsearch-head查看
面试:https://blog.csdn.net/abcd1101/article/details/89010070
深分页问题:https://blog.csdn.net/weixin_40341116/article/details/80821655
实战:
ElasticsearchTemplate 、 TransportClient
BoolqueryBuilder: termQuery matchQuery filter must should
term搜索时不分词,match搜索时分词
query和filter:query context会进行相关性算分,有_score返回;filter不会进行相关性算分
rangeQuery
SortBuilder:
FieldSortBuilder; 属性值排序,按某个字段进行排序
GeoDistanceSortBuilder:根据地理位置排序
ScoreSortBuilder: 根据score排序
ScriptSortBuilder: 根据自定义脚本排序
SearchRequestBuilder
SearchType: dfs_query_then_fetch query_then_fetch .......
.setSize()
.setPreference //每次都查询主分片,防止多次查询结果不一致
.setFrom() //分页
.setScroll() //此处容易引发问题?
SearchResponseBuilder
SearchHit
10000 深分页问题
获取分词结果 ikRequest 调用es获取ik 分词结果 -> 对结果做筛选,如热点文案
深分页问题:
分页越深则越容易OOM,即便不OOM,也很消耗CPU和内存资源
Es为了避免深分页,不允许使用(from&size)查询10000条以后的数据,因此如果要查询第10000条以后的数据,要使用ES提供的scroll(游标)来查询
index.max_result_window:10000作为保护措施
网友评论