1、工作原理:
ElasticSearch(简称ES)是一个基于Lucene构建的开源、分布式、RESTful的全文本搜索引擎。
,它提供了搜索程序的核心索引和搜索模块,,ElasticSearch却也不仅只是一个全文本搜索引擎,它还是一个分布式实时文档存储,其中每个field均是被索引的数据且可被搜索;也是一个带实时分析功能的分布式搜索引擎,并且能够扩展至数以百计的服务器存储及处理PB级的数据。
索引是一种数据结构,它允许对存储在其中的单词进行快速随机访问。
2、重要概念:
索引(Index)
ES将数据存储于一个或多个索引中,索引是具有类似特性的文档的集合。类比传统的关系型数据库领域来说,索引相当于SQL中的一个数据库,或者一个数据存储方案(schema)。
索引由其名称(必须为全小写字符)进行标识,并通过引用此名称完成文档的创建、搜索、更新及删除操作。一个ES集群中可以按需创建任意数目的索引。
类型(Type)
类型是索引内部的逻辑分区(category/partition),然而其意义完全取决于用户需求。因此,一个索引内部可定义一个或多个类型(type)。一般来说,类型就是为那些拥有相同的域的文档做的预定义。
例如,在索引中,可以定义一个用于存储用户数据的类型,一个存储日志数据的类型,以及一个存储评论数据的类型。类比传统的关系型数据库领域来说,类型相当于“表”。
文档(Document)
文档是Lucene索引和搜索的原子单位,它是包含了一个或多个域的容器,基于JSON格式进行表示。
文档由一个或多个域组成,每个域拥有一个名字及一个或多个值,有多个值的域通常称为“多值域”。每个文档可以存储不同的域集,但同一类型下的文档至应该有某种程度上的相似之处。
映射(Mapping)
ES中,所有的文档在存储之前都要首先进行分析。用户可根据需要定义如何将文本分割成token、哪些token应该被过滤掉,以及哪些文本需要进行额外处理等等。
另外,ES还提供了额外功能,例如将域中的内容按需排序。事实上,ES也能自动根据其值确定域的类型。
接下去再说说ES Cluster相关的一些概念。
集群(Cluster)
ES集群是一个或多个节点的集合,它们共同存储了整个数据集,并提供了联合索引以及可跨所有节点的搜索能力。
多节点组成的集群拥有冗余能力,它可以在一个或几个节点出现故障时保证服务的整体可用性。
集群靠其独有的名称进行标识,默认名称为“elasticsearch”。节点靠其集群名称来决定加入哪个ES集群,一个节点只能属一个集群。
如果不考虑冗余能力等特性,仅有一个节点的ES集群一样可以实现所有的存储及搜索功能。
节点(Node)
运行了单个实例的ES主机称为节点,它是集群的一个成员,可以存储数据、参与集群索引及搜索操作。
类似于集群,节点靠其名称进行标识,默认为启动时自动生成的随机Marvel字符名称。
用户可以按需要自定义任何希望使用的名称,但出于管理的目的,此名称应该尽可能有较好的识别性。
节点通过为其配置的ES集群名称确定其所要加入的集群。
分片(Shard)和副本(Replica)
ES的“分片(shard)”机制可将一个索引内部的数据分布地存储于多个节点,它通过将一个索引切分为多个底层物理的Lucene索引完成索引数据的分割存储功能,这每一个物理的Lucene索引称为一个分片(shard)。
每个分片其内部都是一个全功能且独立的索引,因此可由集群中的任何主机存储。创建索引时,用户可指定其分片的数量,默认数量为5个。
Shard有两种类型:primary和replica,即主shard及副本shard。
查询和过滤(Queries and Filters)
Elasticsearch中存在两种DSL:查询DSL(query DSL)和过滤DSL(filter DSL)。
查询子句和过滤子句的自然属性非常相近,但在使用目的上略有区别。
简单来讲,当执行full-text查询或查询结果依赖于相关度分值时应该使用查询DSL,当执行精确值(extac-value)查询或查询结果仅有“yes”或“no”两种结果时应该使用过滤DSL。
Filter DSL计算及过滤速度较快,且适于缓存,因此可有效提升后续查询请求的执行速度。
而query DSL不仅要查找匹配的文档,还需要计算每个文件的相关度分值,因此为更重量级的查询,其查询结果不会被缓存。
不过,得益于倒排索引,一个仅返回少量文档的简单query或许比一个跨数百万文档的filter执行起来并得显得更慢。
Elasticsearch支持许多的query和filter,但最常用的也不过几种。
Filter DSL中常见的有term Filter、terms Filter、range Filter、exists and missing Filters和bool Filter。
而Query DSL中常见的有match_all、match 、multi_match及bool Query。鉴于时间关系,这里不再细述,朋友们可参考官方文档学习。
Queries用于查询上下文,而filters用于过滤上下文,不过,Elasticsearch的API也支持此二者合并运行。
分词与模糊查询:
1、分词快速的原理:
为方便全文本字段进行查询,对文本进行了分析(analyzes),然后使用结果建立一个倒排索引
用倒排索引(inverted index)做快速全文搜索,由文档中出现的唯一单词列表,及单词位置组成;
{倒排索引解释:
单词词典--倒排文件组成 的哈希+链表形式/ 树形结构,
单词顺序排列;文件存放在磁盘存储倒排索引的物理文件 }
2、Analyze分析过程: _analyze帮助分析每一个field 如何被索引返回的;
token:实际被存储在索引中的词
position:指明词在原文本中的第几个出现的
start_offset、 end_offset:词在原文本中占据的开始结束位置
analyze类型:
①、默认类型,解析为: 床、前、明、月、光
GET /_analyze?
{"analyzer" : "standard", "text" : "床前明月光"}
②指定分析使用空格,解析为:床前、明月光
GET /_analyze?
{
"analyzer" : "whitespace",
"text" : "床前 明月光"}
③使用ik分析器:解析为:床前明月光、床前、明月光、明月、明、月光、月、光
GET /tystock/_analyze?
{ "analyzer": "ik_max_word", "text" : "床前明月光"}
④拼音分析器:chuang、cqmyg、qian、ming、yue、guang
GET /tystock/_analyze?
{ "analyzer": "pinyin", "text" : "床前明月光"}
3、模糊匹配:
1、boolQueryBuilder.must(QueryBuilders.wildcardQuery(property, "*" + String.valueOf(value) + "*"));
2、boolQueryBuilder.must(QueryBuilders.matchQuery(property, value).minimumShouldMatch("80%"));
模拟字符串数据存储:
localhost:9200/yigo-redist.1/_analyze?analyzer=default&text=全能片(前)---TRW-GDB7891AT刹车片自带报警线,无单独报警线号码,卡仕欧,卡仕欧,乘用车,刹车片
索引为 yigo-redist.1 ,使用分词器:default 对text进行字符串解析:
解析后: 全能、 片、前 、trw-gdb7891at、刹车片、自带、 报警、线、无、单独、报警、线、号码、卡;
【原理】:拆分成了很多词组碎片,存储在了索引数据中
关键词查询:
localhost:9200//yigo-redist.1/_analyze?analyzer=default_search&text=gdb7891
解析后:gdb7891
【原理】:只提供索引碎片:gdb7891, match-query无法索引到数据;
关键词使用存储的分词器查询
localhost:9200//yigo-redist.1/_analyze?analyzer=default&text=gdb7891
解析后:gdb7891、gdb、7891
【原理】:拆分成多个碎片,会查询到多个匹配的数据;
4、_source、 _all、 store、 index属性精讲
https://blog.csdn.net/napoay/article/details/62233031
a, _source存储的什么?
原始文档{xxx:,xxx:}
b, store属性的true或false和_source字段有什么关系?
store属性设置为true和_all有什么关系?
index属性又起到什么作用?
什么时候设置store属性为true?
什么时候应该开启_all字段?
elasticsearch原理:
1,存储保存 ( _source )原始文档{xxx:,xxx:}
保存是保存一份原始文档、一份倒排索引(倒排记录表,记录词项和文档之间对应关系)
2,用户查询
首先将请求"中国人" 分词为"中国人","中国","人";
根据索引去查找,获取文档信息,返回。
字段创建倒排索引规则:由字段的 index 属性控制;
analyzed :字段被索引,会做分词,可搜索。 (分词搜索)
not_analyzed :字段值不分词,会被原样写入索引。(完全匹配)
no :字段不写入索引,当然也就不能搜索
store属性:用于指定是否将原始字段写索引, 默认取值 no,
主要用于设置关键字的高亮,如果存在 _source 中的原始文档也能实现高亮;因此,store和 _source存在一个。
设置高亮根据 偏移位置设置。
一、_source: 默认是存储的,当字段内容非常多的时候,会占用大量的内存,因此,可以设置不索引部分数据。
关闭_source { "yourtype":{ "_source":{ "enabled":false } } } |
_source仅存储几个字段的原始值 { "yourtype":{ "_source":{ " includes ": ["field1","field2"] //包含字段 "excludes":["field1","field2"] //不包含字段 }, "properties": { ... } } } |
二、 _all 用于整个文档搜索,不指定某一个字段进行搜索;该字段默认是关闭的
开启_all { "yourtype":{ " _all ":{ "enabled":true } } } |
设置某个字段是都包含在 _all中 { "yourtype": { "properties": { "field1": { "type": "string", "include_in_all": false }, "field2": { "type": "string", "include_in_all": true } } } } |
三、开始 store 保存所有原始值;
开启所有字段都保存在 _all中并且存储原始值: PUT test/test/_mapping { "test": { "_all": { "enabled": true, "store": true } } } //对 _all字段搜索并设置高亮 POST test/_search { "fields": ["_all"], "query": { "match": { "_all": "中国人" } }, "highlight": { "fields": { "_all": {} } } } //query_string 和 simple_query_string默认就是查询 _all字段 GET test/_search { "query": { "query_string": { "query": "共产党" } } } |
https://blog.csdn.net/napoay/article/details/62233031
设置index,_score,analyzed,store
设置 index 和score ; 设置test索引不保存_source, title字段索引但不分析, title字段索引但不分析,字段原始值写入索引, content字段为默认属性 DELETE test //删除索引 PUT test //插入索引 PUT test/test/_mapping //构建索引的mapping { "test": { "_source": { "enabled": false }, "properties": { "title": { "type": "string", "index": "not_analyzed", "store": "true" }, "content": { "type": "string" } } } } |
5、分词器及自定义分词器,IK分词,安装及使用;
https://blog.csdn.net/ty4315/article/details/52475474?utm_source=blogxgwz1
https://blog.csdn.net/jam00/article/details/52983056?utm_source=blogxgwz0
https://blog.csdn.net/yu280265067/article/details/71107658?utm_source=blogxgwz2
6、es 在查询时,指定搜索类型的执行流程和差异:
QUERY_THEN_FETCH
QUERY_AND_FEATCH
DFS_QUERY_THEN_FEATCH
DFS_QUERY_AND_FEATCH
https://blog.csdn.net/wangyunpeng0319/article/details/78218332
7、相关读评分详解与自定义评分:
https://blog.csdn.net/paditang/article/details/79098830