一、基本属性介绍
1.包含搜索和聚合两大功能
2.天生分布式结构,支持水平扩展,可以是多个节点甚至是几百个节点
3.Restful风格的接口接入,可以多语言使用
元数据
4.事务性没有关系型数据库强大
document 文档(相当于表中每一行数据)
所有可搜索数据的最小单元,相当于关系型数据库的一条记录;
会被序列化成Jason格式;
每个文档都有自己的唯一id,这个id可以指定,也可以由es自动生成,文档的格式比较灵活不需要预先定义格式
其中的_version(和type同级)版本号,可以通过版本号控制来处理并发读写,同一个id即使被删除version也会增加
index 索引(相当于表)
索引是文档的容器,是一类文档的结合
索引中有Mapping(相当于定义表结构,指明字段名字段类型),Setting(设置索引的数据分布,物,7.0理层面的配置),Type7.0之前一个索引可以有多个type,7.0之后一个索引只有一个type
注:索引也可以做为一个动词来理解,表示一个文档写入es的过程。
二、节点、集群、分片、副本
节点
在不同的角度,节点可以划分为不同的类型:
Master节点多节点部署,会有选举机制选举master节点,只有master节点能修改集群状态。
集群状态:所有节点的信息
所有的索引和相关的Mapping与Setting信息
分片的路由信息
Data Node数据节点:存储数据,当一个节点不够时可以水平扩展一个数据节点
Coordnating Node负责接收客户端的请求,将请求分发到合适的节点,最终将结果汇总到一起,es中每个节点默认都有这个职责
冷热节点冷节点可以用来存储比较旧的数据,配置也可以比较低,,热节点可以用来存储比较活跃的数据配置较高
分片
主分片,用以解决数据水平扩展的问题。通过分片可以将数据水平分散到集群内的所有节点上
一个分片是一个运行的Lucence实例
主分片数在索引创建时指定,后续不允许修改,除非Reindex
副本分片,用以解决数据高可用的问题。副本分片是主分片的拷贝,分片书可以动态调整
没有副节点只有副分片
获取集群健康状况
GET _cluster/health Green:主副分片都正常 Yellow 主分片正常,有副分片未能正常分配
Red:有主分片未能分配
三、基本操作
文档的基本操作包括
Index (根据id 有的话就是删除再添加,没有的话就直接创建)
Create(直接创建,id冲突会报错)
Update(根据id修改)
Delete(根据id删除)
添加一条文档 PUT user/_doc/1 这个id有值会先删除再添加,没值直接添加
PUT只能用来做index索引或者_create创建索引操作
PUT users/_create/1 表示创建一个id为1的文档,如果id已经存在会报错
个人感觉_doc相当于一个占位符,没有意义时就用它
POST根据id做修改 也可以通过这个命令在原来的文档上增加字段
POST users/_doc 表示创建一个文档,自动生成id
批量操作:
批量执行语句 关键字 _bulk
批量获取 _mget
批量查询 关键字 _msearch
四、倒排索引和正排索引
正排索引:文档id -->文档内容-->关键字
倒排索引:关键字-->文档内容-->文档id
倒排索引包含的部分:
单词词典,记录了文档所有的单词和单词与倒排列表的关联关系
倒排列表:组要是倒排索引项(文档id、词频、位置、偏移量)
ES中json文档中的每个字段都有自己的倒排索引,也可以在配置文件中指定某些字段不做索引
分词器:es内置了很多分词器,可以根据需要指定,也可以设置近义词,停用词
五、es的查询
匹配的形式:
1.可以在一个index中匹配也可以在多个index中匹配
2.可以在一个字段中匹配也可以在多个所有字段中匹配,默认在所有字段中索引
3.入参可以是一个关键字,也可以是多个关键字,关键字之间支持集合式的关系(or,and,must,
not must),也支持根据范围查询(时间范围,数据范围)
4.查询结果也可以像MySQL一样指定字段,也可以按字段排序
URI Search
是用url加get的方式查询
Request Body Search
基于json格式的查询
搜索结果可以根据需要过滤,过滤掉不需要的数据
也可以根据搜索相关性打分进行排序,这个排序也可以根据业务需求来排序
1.URI Search
在URL中设置属性:
q:指定查询的语句 就是关键字
df:默认字段,不指定时,会对所有字段进行查询
Sort:排序
from和size:用于分页
profile:查看查询是如何被执行的
GET /movies/_search?q=title:"Beautiful Mind" 双引号表示查询title中既包含Beautiful又包含Mind的数据
GET /movies/_search?q=title(Beautiful Mind) 括号表示查询title中包含Beautiful或者包含Mind的数据(分组)
左边的是关系,右边的是范围
也支持通配符查询b.*,模糊查询(兼容错误输入 beautifl 可匹配上 beautiful),相识度查询
2.Request Body Search
个人觉得Request Body比较好用
(1)简单查询
可以指定查询的列,也可以分页查询,不只这种方式其他查询方式也可以这样查
GET _index/_search
{
"_source":["列名1","列名2","列名3"],
"from":0 起始页
"size":10 每页显示条数
"query":{
"match_all":{} 查询所有的文档
}
}
(2)脚本查询
也支持根据脚本计算,将将计算后的结果拼装成一个新列,painless是一种脚本
将order_date一列的值后边加一个“hello”,在结果集中作为一个新的列new_field,下面这个代码中除了new_field和“_hello”,其他的基本上都是关键字
一般情况下需要这种脚本计算的业务,像订单的对于金额的汇率转换之类的
(3)复合查询
支持根据关键字组合查询,or,and,,支持多个关键字严格按照顺序匹配或多个关键字按照一定顺序匹配
技术关键字Match
GET /_index/_doc/_search
{
"query":{
"match":{
"comment":"Last Christmas"相当于是or,包含一个或两个的文档都会被匹配
}
}
}
GET /_index/_doc/_search
{
"query":{
"match":{
"comment":"Last Christmas"
“operator”:"AND"指定是and
}
}
}
技术关键字Match_Phrase
GET /_index/_doc/_search
{
"query":{
"match_phrase":{
"query":"Last Christmas"
“slop”:1没有这个属性表示必须挨着,有这一个属性表示按固定间隔
}
}
}
(4)基于词项的精确查询 term
必要条件:列是一个整体,查询的词是一个整体
如果一个列包含的字很多,像描述类的列,而且这个列做了分词,这个时候拿描述中的一句话去搜索是搜索不到内容的,因为倒排索引中是按词来做的,用一句话去精确匹配是匹配不到的,可以按照下边这样的方式来:
1.利用mapping设置多字段类型,将要搜索的列设置一个keyword类型的列,然后在搜索时利用
term.keyword表示是精确匹配 这样就解决问题了,同时也可以利用filter属性表示不用打分,提高效率。
联合表达一下解决的两个必要条件
六、index中的mapping
1.Mapping的作用:
定义索引中字段的名称
定义索引中字段的类型:Text/Keyword Date Integer/Floating Boolean
复杂类型(对象嵌套对象) 针对地理数据的类型
字段倒排索引设置:字段需不需要索引,字段需不需要分词,
字段索引的级别:关键字 doc_id, 关键字 doc_id 词频 , 关键字 doc_id 词频 所在行
关键字 doc_id 词频 所在行 所在列
正常一个type有一个mapping,但是7.0之后就没有这个限制了
2.文档的属性Dynamic 等于true 表示走es默认的mapping,自动根据字段的值设置字段的类型;
3.如何对属性为null的值进行搜索
mapping中有null_value属性,当某列存在null值时,在mapping配置中将这个列的value_null:“NULLL”
4.copy_to Mapping中设置中可以将多个列的值拷贝到一个新列中,搜索时可以按照这个新列搜索,但是真正匹配的还是按照原始的列进行的匹配
5.当某个列的值是一个数组时,这个列的类型不是数组而是数组的泛型 如果是一个text类型的数组,这个列的类型是text
6.多字段类型,可以为一个字段设置子字段,像支持拼音搜索,为一个字段增加一个拼音子字段,子字段按照拼音分词
7.精确值和全文本的区别:精确值(数值,字符串,日期)不用做分词,全文本一般做分词
七、索引模板
Index Templates (全局的模板)
相当于设置全局的索引属性,当新建的索引中某些属性没有设置时就会走模板中的属性,如果有多个Index Templates会先采用order值高的template
Dynamic Index Templates (在具体index上的模板)
在具体的index上设置索引模板,像将所有text类型的列设置成不可分词等
Dynamic 索引模板和Mapping中的Dynamic是有区别的
八、聚合
四种聚合方式:Bucket/Metric/Pipeline/Matrix
Metric 统计数量的查询
min/max/sum/avg 一次输出一个也可以一次输出多个
Bucket分组的 查询
也可以将分组和统计联合起来查询
================================基础知识测试==================================
1.添加一个没有索引的文档,es会走怎样的流程?
默认情况下会创建一个索引(也可以通过设置不允许自动创建索引这样会报错),同时自己设置Mapping,当然还要看有没有合适的Index Template
2.es7中唯一合法的type是什么?
_doc
3.分词包括哪几部分?
停用词、近义词、分词器
4.Request Body Search中Match和Match Phrase的区别?
Match默认是or的查询 也可以通过operator设置成and
Match Phrase 是对多个关键字进行整体查询,也可以通过slop设置关键字之间的间隔
5.Mapping的dynamic设置成strict或者false有什么区别?
strict 文档不可添加,列不可索引,mapping不会修改
false 文档可以添加,列不可索引,mapping不会修改
6.可以把一个字段的类型从"integer"改成“long”,因为这两个类型是兼容的
错,修改字段类型相当于修改了mapping,是需要ReIndex的
================================基础知识测试==================================
一、相关性算分:
_score 将整体的一个查询语句“****************”进行分词,将分的每个词去和所有文档、某个文档去做比较(词频,次数)等,然后将结果加权相加,得到的就是某个文档的打分
Boosting来影响打分:Boosting可以在索引、字段、查询子条件三个层面设置 (在查询语句中设置)
boost > 1 提升相关度 0 < boost < 1 降低相关度 boost < 0 贡献负分
也可以通过函数:Function Score Query函数来设置搜索结果的排序规则:随机排序、用某一列来影响打分结果(点赞数高的排在前)
二、query多条件查询
must must_not should filter
注意上边的keyword表示是对查询的关键字不分词,是看文档是否包含这个关键字整体
如果想和列精确匹配需要将这个列设置一个keyword子列
修改bool查询的结构影响布尔查询的算分
左边:四个条件对算分的影响是一样的, 右边:最后两个条件合起来和前边一个条件的算法相同
总结一下学过的查询语句
query
bool、constant_score
filter、should、must、must_not
term、match、match_phrase
三、查询模板和Index Alias
1.定义查询模板
POST _scripts/tmb
{
"script":{
"lang":"mustache"
"source":{
"_source":[ 指定查询的列
“title","overview"
],
"size":20, 设置查询条数
"query":{
"multi_match":{
"query":”{ {q} }“ 设置请求参数
”fields":["title","overview"]
}
}
}
}
}
关于模板的语法很丰富,可以设置比较灵活
2.调用模板
POST tmdb/_search/template
{
"id":"tmdb", 指定模板id
"params":{
"q":"basketball with cartoon aliens" 输入请求参数
}
}
3.Index Alias相当于是索引副本
可以取一个别名存储一个索引中的全部或者部分(根据指定条件过滤)数据
例如:将某个索引的数据按天存一个副本,这样能减少查询范围
四、搜索的扩展功能(根据错误关键字推测结果,自动补全上下文,跨集群搜索)
1.根据错误的关键字返回推荐的结果
term suggester\phrase suggester 两种api
将输入的关键字,经过最小的变动找到相近的关键字进行搜索
2.自动补全上下文
completion suggester
因为自动补全对性能要求比较严格所以未倒排索引,而是将数据编码成FST格式和索引一起存放,加载进内存,速度很快
FST只能用于前缀查找
使用:在mapping中设置列的type是completion就行