一.ES核心概念
elasticsearch 是面向文档的,一切都是 Json
ES关系型数据库的对比记忆:
ElasticSearch | 关系型数据库 |
---|---|
索引(indices) | 数据库(database) |
类型(types) | 表(tables) |
文档(documents) | 行(rows) |
字段(fields) | 列(columns) |
elasticsearch(集群)中可以包含多个索引(数据库),每个索引中包含多个类型(表),每个类型中包含多个文档(行),每个文档中包含多个字段(列)。
几个相关概念:
概念 | 说明 |
---|---|
indices(索引库) | indices是index的复数,代表许多的索引, |
type(类型) | 类型是模拟mysql中的table概念,一个索引库下可以有不同类型的索引,比如商品索引,订单索引,其数据格式不同。不过这会导致索引库混乱,因此未来版本中会移除这个概念 |
document(文档) | 存入索引库原始的数据。比如每一条商品信息,就是一个文档 |
field(字段) | 文档中的属性 |
mappings(映射配置) | 字段的数据类型、属性、是否索引、是否存储等特性 |
node(节点) | 节点就是es实例 |
cluster(集群) | 一个集群有多个节点 |
shard(分片) | 索引分片,es将一个完整的索引分为多个分片 |
replica(副本) | 每个shard可以设置一定数量的副本,写入的文档同步给副本,副本可以提供查询功能,分摊系统的都负载 |
mapping支持的属性:
-
enabled:仅存储、不做搜索和聚合分析
-
"enabled":true (缺省)| false
-
-
index:是否构建倒排索引(即是否分词,设置false,字段将不会被索引)
-
"index": true(缺省)| false
-
-
index_option:存储倒排索引的哪些信息
-
"index_options": "docs" # 4个可选参数 # docs:索引文档号 # freqs:文档号+词频 # positions:文档号+词频+位置,通常用来距离查询 # offsets:文档号+词频+位置+偏移量,通常被使用在高亮字段 # 分词字段默认时positions,其他默认时docs
-
-
norms:是否归一化相关参数、如果字段仅用于过滤和聚合分析、可关闭
-
"norms": {"enable": true, "loading": "lazy"} # 分词字段默认配置,不分词字段:默认{“enable”: false},存储长度因子和索引时boost,建议对需要参加评分字段使用,会额外增加内存消耗
-
-
doc_value:是否开启doc_value,用户聚合和排序分析
-
"doc_value": true(缺省)| false # 对not_analyzed字段,默认都是开启,分词字段不能使用,对排序和聚合能提升较大性能,节约内存
-
-
fielddata:是否为text类型启动fielddata,实现排序和聚合分析
-
"fielddata": {"format": "disabled"} # 针对分词字段,参与排序或聚合时能提高性能,不分词字段统一建议使用doc_value
-
-
store:是否在_source之外再独立存储一份,默认不存储。(因为_sourse已经存储了所有的字段)
-
"store": false(默认)| true
-
-
coerce:是否开启自动数据类型转换功能,比如:字符串转数字,浮点转整型
-
"coerce: true(缺省)| false"
-
-
multifields:灵活使用多字段解决多样的业务需求
-
dynamic:控制mapping的自动更新,(慎用!)
-
"dynamic": true(缺省)| false | strict
-
-
data_detection:是否自动识别日期类型
-
data_detection:true(缺省)| false
-
-
analyzer:指定分词器,默认分词器为standard analyzer
-
"analyzer": "ik"
-
-
boost:字段级别的分数加权,默认值是1.0 (5.0.0版本之后废弃)
-
"boost": 1.23
-
-
fields:可以对一个字段提供多种索引模式,同一个字段的值,一个分词,一个不分词
-
"fields": {"raw": {"type": "string", "index": "not_analyzed"}}
-
-
ignore_above:超过100个字符的文本,将会被忽略,不被索引
-
"ignore_above": 100
-
-
include_in_all:设置是否此字段包含在_all字段中,默认时true,除非index设置成no
-
"include_in_all": true
-
-
null_value:设置一些缺失字段的初始化,只有string可以使用,分词字段的null值也会被分词
-
"null_value": "NULL"
-
-
position_increament_gap:影响距离查询或近似查询,可以设置在多值字段的数据上或分词字段上,查询时可以指定slop间隔,默认值时100
-
"position_increament_gap": 0
-
-
search_analyzer:设置搜索时的分词器,默认跟analyzer是一致的,比如index时用standard+ngram,搜索时用standard用来完成自动提示功能
-
"search_analyzer": "ik"
-
-
similarity:默认时TF/IDF算法,指定一个字段评分策略,仅仅对字符串型和分词类型有效
-
"similarity": "BM25"
-
-
trem_vector:默认不存储向量信息,支持参数yes(term存储),with_positions(term+位置),with_offsets(term+偏移量),with_positions_offsets(term+位置+偏移量)对快速高亮fast vector highlighter能提升性能,但开启又会加大索引体积,不适合大数据量用
-
"trem_vector": "no"
-
mapping字段设置流程:
物理设计:
elasticsearch 在后台把每个索引划分为多个分片,每个分片可以在集群中的不同服务器间迁移。
要注意的是:Elasticsearch 本身就是分布式的,因此即便你只有一个节点,Elasticsearch 默认也会对你的数据进行分片和副本操作,当你向集群添加新数据时,数据也会在新加入的节点中进行平衡。
什么时候会触发分片?
- 创建或者删除索引
- 修改replica
- 再均衡
- 增减节点
逻辑设计:
elasticsearch 是面向文档的,所以在查找时,文档就是最小单位。当在索引中查找一个文档时,顺序为:索引
-> 类型
-> 文档ID
,这里的文档ID是一个字符串,所以不必是整数。
倒排索引:
博客文章(原始数据) | 索引列表(倒排索引) | ||
博客文章id | 标签 | 标签 | 博客文章id |
1 | python | python | 1, 2, 3 |
2 | python | linux | 3, 4 |
3 | linux, python | ||
4 | linux |
如果需要查找标签为linux
的文章,只需要直接查找博客文章id为3,4 的就可以了。
二.IK分词器
ik分词器提供两种算法:
ik_smart
和is_max_word
。ik_smart
表示最少切分,is_max_word
表示最细粒度划分
有时候我们会使用一些ik”没有见过的新词“,那么需要自己来将这些新词加入拓展分词词典中。具体方法:
- 在
elasticsearch-7.6.2\plugins\ik\config
目录下创建mywords.dic
词典(名称可以自定义) - 在
elasticsearch-7.6.2\plugins\ik\config\IKAnalyzer.cfg.xml
添加创建的拓展词典文件的名称
三. Rest 风格
1.基础命令
restful是一种软件架构风格,而不是标准,只提供一组设计原则和约束条件。
method | url地址 | 描述 |
---|---|---|
PUT | localhost:9200/索引名称/类型名称/文档id | 创建(指定id)文档 |
POST | localhost:9200/索引名称/类型名称 | 创建(随机id)文档 |
POST | localhost:9200/索引名称/类型名称/文档id/_update | 修改文档 |
DELETE | localhost:9200/索引名称/类型名称/文档id | 删除文档 |
GET | localhost:9200/索引名称/类型名称/文档id | 查询文档 |
POST | localhost:9200/索引名称/类型名称/_search | 查询所有数据 |
2.测试命令(新建)
创建一个索引
PUT /索引名/类型名/文档id
{
请求体
}
创建之后查看:
四.ES字段类型
一级分类 | 二级分类 | 具体类型 |
---|---|---|
核心类型 | 字符串类型 | string, text, keyword |
整数类型 | integer, long, short, byte | |
浮点类型 | double, float, half_float, scaled_float | |
逻辑类型 | boolean | |
日期类型 | date | |
范围类型 | range | |
二进制类型 | binary | |
复合类型 | 数组类型 | array |
对象类型 | object | |
嵌套类型 | nested | |
地理类型 | 地理坐标类型 | geo_point |
地理地图 | geo_shape | |
特殊类型 | IP类型 | ip |
范围类型 | completion | |
令牌计数类型 | token_count | |
附件类型 | attachment | |
抽取类型 | percolator |
string
字符串类型,es中最常用的类型,官方文档
比较重要的参数:
index分析
- analyzed(默认)
- not_analyzed
- no
store存储
- true 独立存储
- false(默认)不存储,从_source中解析
Numeric
数值类型,注意numeric
并不是一个类型,它包括多种类型,比如:long
,integer
,short
,byte
,double
,float
,每种的存储空间都是不一样的,一般默认推荐integer
和float
。官方文档参考
重要的参数:
index分析
- not_analyzed(默认) ,设置为该值可以保证该字段能通过检索查询到
- no
store存储
- true 独立存储
- false(默认)不存储,从_source中解析
date
日期类型,该类型可以接受一些常见的日期表达方式,官方文档参考。
重要的参数:
index分析
- not_analyzed(默认) ,设置为该值可以保证该字段能通过检索查询到
- no
store存储
- true 独立存储
- false(默认)不存储,从_source中解析
format格式化
- strict_date_optional_time||epoch_millis(默认)
- 你也可以自定义格式化内容,比如
"date": {
"type": "date",
"format": "yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
IP
这个类型可以用来标识IPV4的地址,官方文档参考
常用参数:
index分析
- not_analyzed(默认) ,设置为该值可以保证该字段能通过检索查询到
- no
store存储
- true 独立存储
- false(默认)不存储,从_source中解析
boolean
布尔类型,所有的类型都可以标识布尔类型,官方文档参考
- False: 表示该值的有:false, “false”, “off”, “no”, “0”, “” (empty string), 0, 0.0
- True: 所有非False的都是true
重要的参数:
index分析
- not_analyzed(默认) ,设置为该值可以保证该字段能通过检索查询到
- no
store存储
- true 独立存储
- false(默认)不存储,从_source中解析
五.索引规则
1.创建规则
PUT /索引名
{
规则
}
如果设置文档类型,那么ES就会默认配置字段类型。
2.查看规则
GET 索引名(/类型名/文档名)
扩展:通过GET _cat/...
命令可以获取es的很多当前信息。
例如:
六.修改
方法一:直接覆盖原文档
PUT /索引名/类型名/文档id
{
请求体
}
这种方法的缺点是:修改时,请求体中需要带上原文档中的所有字段,否则原文档中的这些字段会被删除。
方法二:
POST /索引名/类型名/文档id/_update
{
需要修改的字段
}
七.关于文档的基本操作
1.创建文档 PUT
PUT /索引名/类型名/文档id
{
各个字段
}
查看elasticsearch-head:
2.更新文档 POST
POST /索引名/类型名/文档id/_update
{
"doc": {
需要修改的字段
}
}
3.查询文档 GET
3.1查询某个文档
GET /索引名/类型名/文档id
3.2通过关键字查询
GET /索引名/类型名/_search?q=关键字1&关键字2
3.3通过请求体查询
GET /索引名/类型名/_search
{
"query":{
"查询规则":{
字段
}
}
}
3.4限定返回字段查询
GET /索引名/类型名/_search
{
"query":{
"查询规则":{
字段
}
},
"_source": ["字段1","字段2"]
}
3.5排序查询
GET /索引名/类型名/_search
{
"query":{
"查询规则":{
字段
}
},
"sort": [
{
"FIELD": {
"order": "desc"
}
}
]
}
3.6分页查询
GET /索引名/类型名/_search
{
"query": {},
"from": 0,
"size": 20
}
其中,from
定义了目标数据的偏移值,size
定义当前返回的事件数目。
默认from为0,size为20,即所有的查询默认仅仅返回前20条数据。
3.7多条件查询
GET /索引名/类型名/_search
{
"query": {
"match": {
"字段": "字段1值 字段2值 ..."
},
}
}
3.8 bool 查询
bool查询是一种复合查询方式,是由一个或多个布尔子句构建的,每个子句都有一个类型化的事件。具体类型是:
关键字 | 描述 |
---|---|
must | 必须匹配, 相当于mysql中的and |
should | 至少有一个匹配, 相当于mysql中的or |
must_not | 必须不匹配,相当于mysql中的not |
filter | 条件过滤 |
(1) must
GET /索引名/类型名/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"FIELD": "TEXT"
}
},
{
"match": {
"FIELD": "TEXT"
}
}
]
}
}
}
表示查询结果必须同时匹配
一个或多个字段,相当于where name=n and age=2
(2) should
GET /索引名/类型名/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"FIELD": "TEXT"
}
},
{
"match": {
"FIELD": "TEXT"
}
}
]
}
}
}
表示查询结果只需要匹配
任意一个字段,相当于where name=n or age=2
(3) must_not
GET /索引名/类型名/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"FIELD": "TEXT"
}
}
]
}
}
}
表示查询结果必须不包含
一个或多个字段,相当于where name!=n
(4) filter
GET /索引名/类型名/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"FIELD": "TEXT"
}
}
],
"filter": [
{"range": {
"FIELD": {
"gte": 10,
"lte": 20
}
}}
]
}
}
}
对查询结果进行条件过滤
3.9 精确查询
term
查询是直接通过倒排索引进行精确查找的,不进行分词器分析,文档中必须包含整个搜索的词汇
3.10 高亮查询
GET /索引名/类型名/_search
{
"query": {}
},
"highlight": {
"fields": {
"字段":{}
}
}
}
自定义高亮条件:
"highlight": {
"pre_tags": "<p class='key' style='color:red'>",
"post_tags": "</p>",
"fields": {
"name":{}
}
八.倒排索引
正排索引(正向索引,forword index):
文档ID -> 单词1,单词2,…,单词n
倒排索引(反向索引,inverted index):
单词x -> 文档1,文档2,…,文档n
正排索引 | 倒排索引 | ||
博客文章id | 标签 | 标签 | 博客文章id |
1 | python | python | 1, 2, 3 |
2 | python | linux | 3, 4 |
3 | linux, python | ||
4 | linux |