ElasticSearch¶
1. 基础篇¶
本文档主要基于 https://www.cnblogs.com/progor/p/11543146.html 这篇博客.
1.1 介绍¶
1.2 基本概念¶
索引 Index: 索引是存储具有相同结构的 Document 的集合, 意义上有点类似关系型数据库中的数据表, 用于存储一系列数据, 比如可以说 “商品” 索引, 一般都是个大类. 注意, 通常我们要避免将 Schema 差异过大的 Document 放在一个 Index 中. 这和底层 Mapping 机制有关. 再 7.0 之前有一个隐藏字段
_type
通常用来做逻辑上的 Table 的划分, 但后来官方发现同一个 Index 下的 Schema 差异太大导致维护的字段过多, 所以从 7.0 开始就限制一个 Index 下只有一个 Type, 也就是说 Type 的概念没有用了. (2021-11-27 目前是 7.5版本)文档 Document: 类似于关系型数据库中的记录, 是 ElasticSearch 的数据存储的基本单位, 格式与 JSON 相同.
域 Field: 类似于关系型数据库中的字段。
1.2.1 索引 Index¶
Links:
创建索引¶
你在插入 Document 时, 如果 Index 还没有被创建, 那么 ES 会自动用默认设置创建这个 Index. 当然你也可以手动创建 Index 并对其进行更精细的配置.
修改索引¶
修改索引主要是修改分片数量, mapping, 分词器, 由于 mapping 和 分词器 涉及很深, 需要前置知识, 所以留到后面讲.
关闭索引¶
关闭索引是为了避免修改索引的配置时他人进行文档读写. 关闭索引后, 就只能获取索引的配置信息, 而不能读写索引中的 Document. 有时候也用于关闭一些无用的索引来减少资源消耗.
索引别名¶
索引别名是一个 “别名”, 但能够像索引名那样使用, 它的使用场景一方面是 “使用更简洁的索引名来获取数据”, 另一个方面是 “通过索引别名来指向索引 (别名B指向索引A), 方便修改指向的索引, 用于解决可能的更换索引的场景 (比如你需要统一修改原有索引的信息, 那你可以新建索引C, C存储了修改后的数据, 更改指向原本索引A的索引别名B指向C).”
1.2.2 文档 Document¶
在 ElasticSearch 中, Document 是 Immutable 并且有 Versioned. 默认情况下你搜索到的都是最新的数据. 比如你插入后对文档某字段进行了修改, 版本号就会 +1. 你在查询的时候返回的结果会带有 _version
字段, 表示该文档的版本号.
1.3 查询¶
Links:
1.3.1 基础查询¶
ES 的查询功能是非常强大且灵活的. 其中作为杀手锏的是搜索引擎中常用的倒排索引. 简单来说, 查询的请求 JSON 长这个样子:
{
"query": {
... 具体的查询
}
}
ES 的查询模式有这几大类:
Leaf query clauses. 主要是三个:
match
全文搜索查询,term
精确值匹配查询,range
数值区间查询.Compound query clauses. 其实就是 Leafe query clauses 的逻辑与或非排列组合. 主要是两个:
bool
逻辑组合,dis_max
文本距离查询. 以及一个特殊的constant_score
指定某些查询条件不参与相关度排序.- 慢查询, 这些查询通常无法有效利用索引
script
在 Query DSL 中写简单的 script, 对数据进行简单处理和匹配.fuzzy
regexp
prefix
wildcard
range
ontext
andkeyword
Joining 跨 Index Join 查询.
match_all
, 全部字段的全文搜索:
{
"query": {
"match_all": {}
}
}
match
, 指定字段的全文搜索:
{
"query": {
"match": {
"字段名": "搜索值"
}
}
}
multi_match
, 使用同一搜索值值搜索多个字段:
{
"query": {
"multi_match": {
"query": "搜索值",
"fields": [
"搜索的字段1","搜索的字段2"]
}
}
}
multi_phrase
, 短语搜索, 不会吧搜索值拆开来搜索:
{
"query": {
"match_phrase": {
"字段": "搜索值"
}
}
}
_source
, 字段过滤, 查询的结果只显示指定字段:
{
"query": {
"查询条件"
},
"_source": [
"显示的字段1",
"显示的字段2"
]
}
highlights
, 高亮查询, 根据查询的关键字来进行高亮, 高亮的结果会显示在返回结果中的 highlight 中, 关键字会被加上<em>标签, 如果想要多字段高亮,也需要进行多字段搜索:
{
"query": {
"查询条件"
},
"highlight": {
"fields": {
"高亮的字段名1": {}
}
}
}
由于对多个字段使用不同搜索值涉及条件拼接, 所以单独讲.
前置知识讲解: 对于条件拼接, 在SQL中有 and, or, not, 在ElasticSearch不太一样, 下面逐一讲解:
bool
: 用来表明里面的语句是多条件的组合, 用来包裹多个条件.should
: 里面可以有多个条件, 查询结果必须符合查询条件中的一个或多个.must
: 里面的多个条件都必须成立.must_not
: 里面的多个条件必须不成立.
1.3.2 过滤 Filter¶
过滤的效果其实有点像条件搜索,不过条件搜索会考虑相关度分数和考虑分词,而过滤是不考虑这些的,过滤对相关度没有影响。过滤一般用于结构化的数据上,也就是通常不用于使用了分词的数据上,通常都会用在数值类型和日期类型的数据上。
在搜索的时候,如果你不希望要搜索的条件会影响到相关度,那么就把它放在过滤中,如果希望影响相关度,那么就放在条件搜索中。 使用过滤时,由于不考虑相关度,所以score固定为1。
文档的过滤filter里面主要有五种字段,range,term,terms,exist,missing。range用于字段数据比较大小;term主要用于比较字符类型的和数值类型的数据是否相等;terms是term的复数版,里面可以有多个用于比较相等的值;exist和missing用于判断文档中是否包含指定字段或没有某个字段(仅适用于2.0+版本,目前已经移除)
1.3.3 聚合 Aggregate¶
Links:
和 SQL 中的 SUM, MAX, MIN 函数类似, ES 也提供了很多聚合函数, 总体而言分三大类:
Metric: 对某个 Field 的值做计算, 例如 Average, Min, Max 都属于这一类
Bucket: 按照值将文档放入不同的 Bucket 中, 和 SQL 中的 GroupBy 类似
Pipeline: 对多个 Aggregation 进行嵌套所形成的管道