互联网网站离不开搜索,本文就来介绍一个热门的全文检索技术:Elasticsearch 。
本 wiki 基于
elasticsearch 6.8.2
。
认识 Elasticsearch
为什么选择 Elasticsearch ?
Mysql & Elasticsearch
较 mysql
等传统的关系型数据库,es
等搜索引擎的优势来自 全文检索
, 即模糊查询。
mysql
使用B+索引
,查询和插入较平衡。es
使用倒排索引
,更倾向查询。但两者复杂度不会有太大差异,差异主要来自设计思路。
mysql & elasticsearch |
全文检索过程 |
---|---|
mysql |
只能对 field 添加索引,且对超长会截取,不会分词。故 keyword 查询走索引,模糊查询全表扫描。 |
elasticsearch |
会建立分词后的索引,模糊查询走索引。 |
Lucene & Solr & Elasticsearch
lucene
,solr
,elasticsearch
都是使用的倒排索引
。
主流搜索引擎 | 说明 | 优劣 |
---|---|---|
Lucene |
Apache的开源软件项目,完全用 Java 编写。 | Lucene 只是一个框架,要充分利用它的功能,需要使用Java,并且在程序中集成 Lucene 。API 强大,使用复杂。 |
Solr |
Apache的开源软件项目,基于 Lucene。 | 成熟的产品。 |
ElasticSearch |
Apache的开源软件项目,基于 Lucene库构建的 Restful 搜索引擎。 | 更轻便易用,增长迅速。 |
Elasticsearch
es
的 API 完全遵循 Rest原则
,可以直接通过 http访问。
es
本质也是一种数据库,很多概念和关系型数据库类似。
type
在7.x
版本会被删除,不要在索引下建立多个类型。
1 | Relational DB -> Databases -> Tables -> Rows -> Columns |
Kibana
kibana
是基于 Node.js 的 elasticsearch
索引库数据统计工具,还提供了索引的控制台 dev tools
。
需要另行安装,访问: http://localhost:5601/
IK分词器
ES
很大的优势来自分词能力,但其原生并不支持中文。需要另行安装中文分词插件 : ik-analyzer 。
使用 Elasticsearch
http示例基于
kibana
的dev tools
。
索引
settings |
说明 |
---|---|
number_of_shards |
分片数 |
number_of_replicas |
每个分片的副本数 |
1 | PUT /demo |
1 | { |
类型
使用 _mapping
可以定义 type
的数据结构,及对应 field
属性。
字段属性 | 说明 |
---|---|
type |
类型,例如:keyword , text , float 等。keyword 是词条,不支持分词; text 支持分词。 |
index |
是否创建索引,默认为 true 。 |
store |
是否二次存储。 |
analyzer |
分词器。 |
1 | PUT demo/_mapping/item |
1 | #! Deprecation: [types removal] Specifying types in put mapping requests is deprecated. To be compatible with 7.0, the mapping definition should not be nested under the type name, and the parameter include_type_name must be provided and set to false. |
查看映射配置
1 | GET /demo/_mapping |
1 | #! Deprecation: [types removal] The parameter include_type_name should be explicitly specified in get mapping requests to prepare for 7.0. In 7.0 include_type_name will default to 'false', which means responses will omit the type name in mapping definitions. |
文档
es
面向 document
, document
是 json
格式的数据。
- 新建文档时,若存在之前定义没有的字段,会自动创建对应字段。
- 文档默认自动生成 id,也可以使用
POST /<index>/<type>/[id]
来指定文档的id。
1 | POST /demo/item |
1 | { |
基础查询
全量查询
1 | GET /demo/item/_search |
匹配查询
涉及 | 说明 |
---|---|
operator |
操作符, or 表示分词 或匹配 ; and 表示分词 且匹配 。 |
minimum_should_match |
最小匹配度,可以使用 具体数字 或 百分比 。 |
1 | GET /demo/item/_search |
1 | { |
多字段匹配
1 | GET /demo/item/_search |
词条匹配
词条匹配是以最小分词直接匹配,一般用于不可分割词条。
单词条
1 | GET /demo/item/_search |
多词条
1 | GET /demo/item/_search |
字段过滤
使用 _source
可以选择关注的字段。
_source |
说明 | |
---|---|---|
"" |
[] |
关注的字段 |
includes |
包含的字段 | |
excludes |
排除的字段 |
1 | GET /demo/item/_search |
1 | { |
高级查询
布尔查询
bool |
说明 |
---|---|
must |
与 |
should |
或 |
must_not |
非 |
1 | GET /demo/item/_search |
模糊查询
可以看出,之前介绍的 match
多是 分词匹配
,并不是像 like
一样完全的模糊查询。模糊查询可以使用 fuzzy
。
1 | GET /demo/item/_search |
范围查询
对于数值型多使用范围匹配,支持 gte
| get
| lte
| lt
。
1 | GET /demo/item/_search |
结果集过滤
filter
可以对结果集过滤,类似于嵌套子查询。
1 | GET /demo/item/_search |
排序
sort
可以对结果集排序。
1 | GET /demo/item/_search |
聚合
除了单纯的查询,还可以使用 聚合
完成统计和分析。
聚合类型 | 说明 | 常见示例 | ||||
---|---|---|---|---|---|---|
桶(bucket) |
按照某个维度对数据进行分组,每一组数据在 es 中称为一个桶 。 |
词条分桶 \ | 阶级分桶 \ | 范围分桶 等 | ||
度量(metric) |
分组完成以后,可以对组中的数据进行聚合运算,例如求平均值、最大、最小、求和等,这些在 es 中称为度量 。 |
平均值 \ | 最大值 \ | 最小值 \ | 求和 \ | 计数 等。 |
词条分桶
- 词条分桶只能针对
keyword
,不可对text
使用。 size
: 查询条数,htis
内容。
1 | GET /demo/item/_search |
1 | { |
阶级分桶
对于数值型的字段,常使用阶级分组。
histogram |
说明 |
---|---|
field |
字段。 |
interval |
间隔。 |
min_doc_count |
最小文档计数,只有大于等于这个数才会显示对应桶。 |
1 | GET /demo/item/_search |
1 | { |
范围分桶
范围分桶与阶梯分桶类似,也是把数字按照阶段进行分组,但是需要指定起始和结束大小。
range |
说明 |
---|---|
field |
指定字段。 |
ranges |
范围,from 起始值, to 结束值。 |
1 | GET /demo/item/_search |
1 | { |
附录
[Mac] 安装 elasticsearch
仅介绍基于
hombrew
的安装方法。
elasticsearch
1 | 安装 |
kibana
1 | 安装 |
ik 分词器
根据 es
版本下载对应安装包
- 下载: ik-analyer
1 | brew info elasticsearch |