全文检索是指计算机索引程序经过扫描文章中的每个词,对每个词创建一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先创建的索引进行查找,并将查找的结果反馈给用户的检索方式。这个过程相似于经过字典中的检索字表查字的过程。html
根据http://lucene.apache.org/java/docs/index.html定义:java
Lucene是一个高效的,基于Java的全文检索库。算法
因此在了解Lucene以前要费一番工夫了解一下全文检索。数据库
那么什么叫作全文检索呢?这要从咱们生活中的数听说起。apache
咱们生活中的数据整体分为两种:结构化数据和非结构化数据。json
固然有的地方还会提到第三种,半结构化数据,如XML,HTML等,当根据须要可按结构化数据来处理,也可抽取出纯文本按非结构化数据来处理。缓存
非结构化数据又一种叫法叫全文数据。安全
参考连接:https://blog.csdn.net/genghaihua/article/details/88946228app
es的底层存储使用lucene,主要包含行存储(storefiled),列存储(docvalues)和倒排索引(invertindex)。dom
大多数使用场景中,没有必要同时存储这三个部分,能够经过下面的参数来作适当调整
1 mapping type index 设置
"_source": {
"enabled": false
}
StoreFiled: 行存,其中占比最大的是_source字段,它控制doc原始数据的存储。在写入数据时,ES把doc原始数据的整个json结构体当作一个string,存储为_source字段。查询时,能够经过_source字段拿到当初写入时的整个json结构体。 因此,若是没有取出整个原始json结构体的需求,能够经过下面的命令,在mapping中关闭_source字段或者只在_source中存储部分字段,数据查询时仍可经过ES的docvalue_fields获取全部字段的值。
注意:关闭_source后, update, update_by_query, reindex等接口将没法正常使用,因此有update等需求的index不能关闭_source。
2 字段doc_values设置
"doc_values": false
控制列存。ES主要使用列存来支持sorting, aggregations和scripts功能。
3 字段索引设置
"index": false
控制倒排索引。ES默认对于全部字段都开启了倒排索引,用于查询。
DSL (domain-specific language),领域特定语言指的是专一于某个应用程序领域的计算机语言,又译做领域专用语言。不一样于普通的跨领域通用计算机语言(GPL),领域特定语言只用在某些特定的领域。
6、倒排索引
正排索引:
倒排索引:
Shard(分片)
一个Shard就是一个Lucene实例,是一个完整的搜索引擎。一个索引能够只包含一个Shard,只是通常状况下会用多个分片,能够拆分索引到不一样的节点上,分担索引压力。
segment
elasticsearch中的每一个分片包含多个segment,每个segment都是一个倒排索引;在查询的时,会把全部的segment查询结果汇总归并后做为最终的分片查询结果返回;
在建立索引的时候,elasticsearch会把文档信息写到内存bugffer中(为了安全,也一块儿写到translog),定时(可配置)把数据写到segment缓存小文件中,而后刷新查询,使刚写入的segment可查。
虽然写入的segment可查询,可是尚未持久化到磁盘上。所以,仍是会存在丢失的可能性的。
因此,elasticsearch会执行flush操做,把segment持久化到磁盘上并清除translog的数据(由于这个时候,数据已经写到磁盘上,不在须要了)。
当索引数据不断增加时,对应的segment也会不断的增多,查询性能可能就会降低。所以,Elasticsearch会触发segment合并的线程,把不少小的segment合并成更大的segment,而后删除小的segment。
segment是不可变的,当咱们更新一个文档时,会把老的数据打上已删除的标记,而后写一条新的文档。在执行flush操做的时候,才会把已删除的记录物理删除掉。
当你对一个文档创建索引时,它仅存储在一个primary shard上。ES是怎么知道一个文档应该属于哪一个shard?当你建立一个新的文档时,ES是怎么知道应该把它存储至shard1仍是shard2? 这个过程不能随机无规律的,由于之后咱们还要将它取出来。它的路由算法是:
shard = hash(routing) % number of primary_shards
routing的值能够是文档的id,也能够是用户本身设置的一个值。hash将会根据routing算出一个数值而后%primary shards的数量。这也是为何primary_shards在index建立时就不能修改的缘由。
咱们能够向这个集群的任何一台NODE发送请求,每个NODE都有能力处理请求。每个NODE都知道每个文档所在的位置因此能够直接将请求路由过去。下面的例子,咱们将全部的请求都发送到NODE1。