索引–保存相关数据的地方,实际上是指向一个或者多个物理分片的逻辑明名空间。
集群内的原理
es支持垂直扩容,水平扩容,但是垂直扩容是有极限的,真正的扩容能力来自于水平扩容(为集群添加更多的节点,并将负载及稳定性型分散到这些节点中)
一个运行中的es实例称为一个节点,集群就是由多个拥有相同cluster.name节点组成,集群中有一个节点会被选中为主节点。主节点负责集群范围内所有索引(存储文档的数据库)及节点的新增,及删除等,主节点不会参与到文档添加及更新,所以只有一个主节点不会成为性能的瓶颈。用户可以把请求发送到任意一个节点,每个节点知道任意文档所在的位置,它能找到文档所在的各个节点并搜集返回到客户端。
集群健康
1 | GET /_cluster/health |
1 | { |
status字段表示集群总体工作状态 green 所有主分片和副分片都正常运行。yellow主分片正常运行,但是不是所有的副分片都正常运行。red有主分片没有正常运行。
索引分片
1 | PUT /{index_name} |
1 | { |
索引–保存相关数据的地方,实际上是指向一个或者多个物理分片的逻辑明名空间。分片是数据的容器,文档被保存在分片里,分片被保存在各个节点里面。当集群规模扩大或者缩小,es会自动迁移分片,使得数据均匀分布在各个节点上面。
一个分片理论上能存储 Integer.MAX_VALUE-128个文档,具体和文档大小,及硬件有关。所以一个索引能存储的最大文档数量由分片数目决定。
数据输入和输出
文档元数据
_index
文档存放在哪儿 索引名字 参照关系数据库的数据库名字
_type
同一个索引下的不同数据类型 参照关系数据库的表名
_version
(版本)号,当文档被修改时版本号递增
_id
_id及 _type 、_index 可以唯一确定一个es文档,可以自己提供,也可以由es生成
_all
将所有字段拼接在一起,用于全文搜索
文档操作
添加文档
1 | PUT /{index}/{type}/{id} |
搜索文档
1 | GET /{index}/{type}/{id} |
更新文档
1 | PUT /{index}/{type}/{id} |
创建文档
1 | POST /{index}/{type}/ |
删除文档
1 | DELETE /{index}/{type}/{id} |
乐观并发控制
es为每个文档维护了一个版本号_version 修改数据的时候可以指定版本号 PUT /{index}/{type}/{id}?version=1
,通过指定想要修改文档的 version
号来达到这个目的。 如果该版本不是当前版本号,我们的请求将会失败。
也可以使用外部系统的版本号PUT /{index}/{type}/{id}?version=1&version_type=external
外部版本号的处理方式和我们之前讨论的内部版本号的处理方式有些不同, Elasticsearch 不是检查当前
_version和请求中指定的版本号是否相同, 而是检查当前
_version是否 *小于* 指定的版本号。 如果请求成功,外部的版本号作为文档的新
_version` 进行存储。
搜索
返回字段
hits
:返回结果中最重要的部分是 hits
,它 包含 total
字段来表示匹配到的文档总数,并且一个 hits
数组包 含所查询结果的前十个文档。在 hits
数组中每个结果包含文档的 _index
、 _type
、 _id
,加上 _source
字段。每个结果还有一个 _score
,它衡量了文档与查询的匹配程度。
took
执行整个搜索请求耗费了多少毫秒。
_shards
参与分片的总数,以及这些分片成功了多少个失败了多少个。
timed_out
询是否超时。
多索引多类型搜索
/_search
在所有的索引中搜索所有的类型
/gb/_search
在 gb
索引中搜索所有的类型
/gb,us/_search
在 gb
和 us
索引中搜索所有的文档
/g\*,u\*/_search
在任何以 g
或者 u
开头的索引中搜索所有的类型
/gb/user/_search
在 gb
索引中搜索 user
类型
/gb,us/user,tweet/_search
在 gb
和 us
索引中搜索 user
和 tweet
类型
/_all/user,tweet/_search
在所有的索引中搜索 user
和 tweet
类型
分页
1 | GET /_search?size=5&from=5 |
映射与分析
es 支持精确搜索和全文搜索,精确搜索就是严格的相等;全文搜索,就是会对词进行分析,比如搜索中国,能得到中华人民共和国 这样的结果
倒排索引
Elasticsearch 使用一种称为 倒排索引 的结构,它适用于快速的全文搜索。一个倒排索引由文档中所有不重复词的列表构成,对于其中每个词,有一个包含它的文档列表。
例如,假设我们有两个文档,每个文档的 content
域包含如下内容:
- The quick brown fox jumped over the lazy dog
- Quick brown foxes leap over lazy dogs in summer
为了创建倒排索引,我们首先将每个文档的 content
域拆分成单独的 词(我们称它为 词条
或 tokens
),创建一个包含所有不重复词条的排序列表,然后列出每个词条出现在哪个文档。结果如下所示:
1 | Term Doc_1 Doc_2 |
现在,如果我们想搜索 quick brown
,我们只需要查找包含每个词条的文档:
1 | Term Doc_1 Doc_2 |
两个文档都匹配,但是第一个文档比第二个匹配度更高。如果我们使用仅计算匹配词条数量的简单 相似性算法 ,那么,我们可以说,对于我们查询的相关性来讲,第一个文档比第二个文档更佳。
倒排索引还会有一些问题,比如,大小写,还有相同意思的单词。这就需要分析器来处理了。
分析与分析器
分析器包含三个部分的功能
字符过滤器
首先,字符串按顺序通过每个 字符过滤器 。他们的任务是在分词前整理字符串。一个字符过滤器可以用来去掉HTML,或者将 &
转化成 and
。
分词器
其次,字符串被 分词器
分为单个的词条。一个简单的分词器遇到空格和标点的时候,可能会将文本拆分成词条。
Token 过滤器
最后,词条按顺序通过每个 token 过滤器 。这个过程可能会改变词条(例如,小写化 Quick
),删除词条(例如, 像 a
, and
, the
等无用词),或者增加词条(例如,像 jump
和 leap
这种同义词)。
内置分析器
标准分析器
标准分析器是Elasticsearch默认使用的分析器。它是分析各种语言文本最常用的选择。它根据 Unicode 联盟 定义的 单词边界 划分文本。删除绝大部分标点。
简单分析器
简单分析器在任何不是字母的地方分隔文本,将词条小写。
空格分析器
空格分析器在空格的地方划分文本。它会产生
语言分析器
特定语言分析器可用于 很多语言。它们可以考虑指定语言的特点。例如, 英语
分析器附带了一组英语无用词(常用单词,例如 and
或者 the
,它们对相关性没有多少影响),它们会被删除。 由于理解英语语法的规则,这个分词器可以提取英语单词的 词干 。
1 | GET /_analyze |
映射
内部对象的数组是如何被索引的。 假设我们有个 followers
数组:
1 | { |
这个文档会像我们之前描述的那样被扁平化处理,结果如下所示:
1 | { |
内部对象如何映射
1 | { |
内部域 可以通过名称引用(例如, first
)。为了区分同名的两个域,我们可以使用全 路径 (例如, user.name.first
) 或 type
名加路径( tweet.user.name.first
)。
查询
查询表达式
一个查询语句 的典型结构:
1 | { |
如果是针对某个字段,那么它的结构如下:
1 | { |
主要的ARGUMENT
match_all
:查询简单的 匹配所有文档。
match
:无论你在任何字段上进行的是全文搜索还是精确查询,match
查询是你可用的标准查询。
multi_match
:查询可以在多个字段上执行相同的 match
查询
range
:查询找出那些落在指定区间内的数字或者时间
term
:查询被用于精确值 匹配,这些精确值可能是数字、时间、布尔或者那些 not_analyzed
的字符串
terms
:terms
查询和 term
查询一样,但它允许你指定多值进行匹配。它查询那些精确匹配的值(包括在大小写、重音、空格等方面的差异)。
exits
:文档中某个属性有值
missing
:同exits相反
多组合查询
1 | { |
排序
1 | GET /_search |
索引管理
创建索引
1 | PUT /my_index |
删除索引
1 | DELETE /my_index |
配置分析器
1 | PUT /spanish_docs |