elasticSearch之API:索引操作
文章目录
一、索引操作
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/index.html
1、创建索引
索引命名必须小写,不能以下划线开头
格式: PUT /索引名称
#创建索引
PUT /es_db#创建索引时可以设置分片数和副本数
PUT /es_db
{"settings" : {"number_of_shards" : 3,"number_of_replicas" : 2}
}#修改索引配置
PUT /es_db/_settings
{"index" : {"number_of_replicas" : 1}
}

2、查询索引
格式: GET /索引名称
#查询索引
GET /es_db#es_db是否存在
HEAD /es_db

3、删除索引
格式: DELETE /索引名称
DELETE /es_db
4、ES倒排索引
当数据写入 ES 时,数据将会通过 分词 被切分为不同的 term,ES 将 term 与其对应的文档列表建立一种映射关系,这种结构就是 倒排索引。如下图所示:

为了进一步提升索引的效率,ES 在 term 的基础上利用 term 的前缀或者后缀构建了 term index, 用于对 term 本身进行索引,ES 实际的索引结构如下图所示:

这样当我们去搜索某个关键词时,ES 首先根据它的前缀或者后缀迅速缩小关键词的在 term dictionary 中的范围,大大减少了磁盘IO的次数。
单词词典(Term Dictionary) :记录所有文档的单词,记录单词到倒排列表的关联关系
常用字典数据结构:https://www.cnblogs.com/LBSer/p/4119841.html
倒排列表(Posting List)-记录了单词对应的文档结合,由倒排索引项组成
倒排索引项(Posting):
文档ID
词频TF–该单词在文档中出现的次数,用于相关性评分
位置(Position)-单词在文档中分词的位置。用于短语搜索(match phrase query)
偏移(Offset)-记录单词的开始结束位置,实现高亮显示

Elasticsearch 的JSON文档中的每个字段,都有自己的倒排索引。
可以指定对某些字段不做索引:
优点︰节省存储空间
缺点: 字段无法被搜索
5、文档映射Mapping
(1)字段类型
核心类型:
- 字符串(string)
text,keyword - 数字类型(Numeric)
long,integer,short,byte,double,float,half_float,scaled_float - 日期类型(Date)
data - 布尔类型(Boolean)
boolean - 二进制类型(binary)
binary
复合类型:
- 数组类型(Array)
Array支持不针对特定的类型 - 对象类型(Object)
Object用于单JSON对象 - 嵌套类型(Nested)
nested用于JSON对象数组
地理类型(Geo):
- 地理坐标(Geo-points)
geo_point用于描述经纬度坐标 - 地理图形(Geo-Shape)
geo_shape用于描述复杂形状,如多边形
特定类型:
- IP类型
ip用于描述ipv4和ipv6 - 补全类型(Completion)
completion提供自动完成提示 - 令牌计数类型(Token count)
token_count用于统计字符串中的词条数量 - 附件类型(attachment)
参考mapper-attachements插件,支持将附件如Microsoft Office格式,Open Document格式,ePub,HTML等等索引为attachment数据类型 - 抽取类型(Percolator)
接受特定领域查询语言(query-dsl)的查询
多字段:
通常用于为不同目的用不同的方法索引同一个字段。例如,string字段可以映射为一个text字段用于全文检索,同样可以映射为一个keyword字段用于排序和聚合。另外,你可以使用standard analyzer,english analyzer,french analyzer来索引一个text字段。
这就是muti-fields的目的。大多数的数据类型通过fields参数来支持muti-fields。
(2)映射
Mapping(映射)
Mapping 是用来定义一个文档(document),以及它所包含的属性(field)是如何存储和 索引的。
比如,使用 mapping 来定义:
哪些字符串属性应该被看做全文本属性(full text fields)。
哪些属性包含数字,日期或者地理位置。
文档中的所有属性是否都能被索引(_all 配置)。
日期的格式。
自定义映射规则来执行动态添加属性。
// 查看 mapping 信息(列出该索引所有字段的类型):
GET bank/_mapping
// 修改 mapping 信息
https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html
mapping其实不需要手动定义,在插入数据时会自动猜测映射类型:
布尔型:trye或者false : boolean
整数:123 : long
浮点数:123.45 : double
字符串,有效日期:2022-06026 : date
字符串:learn elasticSearch : string
(3)动静态映射
Mapping类似数据库中的schema的定义,作用如下:
定义索引中的字段的名称
定义字段的数据类型,例如字符串,数字,布尔等
字段,倒排索引的相关配置(Analyzer)
ES中Mapping映射可以分为动态映射和静态映射。
动态映射:
在关系数据库中,需要事先创建数据库,然后在该数据库下创建数据表,并创建表字段、类型、长度、主键等,最后才能基于表插入数据。而Elasticsearch中不需要定义Mapping映射(即关系型数据库的表、字段等),在文档写入Elasticsearch时,会根据文档字段自动识别类型,这种机制称之为动态映射。
静态映射:
静态映射是在Elasticsearch中也可以事先定义好映射,包含文档的各字段类型、分词器等,这种方式称之为静态映射。
动态映射(Dynamic Mapping)的机制,使得我们无需手动定义Mappings,Elasticsearch会自动根据文档信息,推算出字段的类型。但是有时候会推算的不对,例如地理位置信息。当类型如果设置不对时,会导致一些功能无法正常运行,例如Range查询
(4)Dynamic Mapping类型自动识别

#删除原索引
DELETE /user#创建文档(ES根据数据类型, 会自动创建映射)
PUT /user/_doc/1
{"name":"cxf","age":32,"address":"长沙麓谷"
}#获取文档映射
GET /user/_mapping

(5)后期更改Mapping的字段类型
新增加字段
dynamic设为true时,一旦有新增字段的文档写入,Mapping 也同时被更新
dynamic设为false,Mapping 不会被更新,新增字段的数据无法被索引,但是信息会出现在_source中
dynamic设置成strict(严格控制策略),文档写入失败,抛出异常

对已有字段,一旦已经有数据写入,就不再支持修改字段定义
Lucene 实现的倒排索引,一旦生成后,就不允许修改
如果希望改变字段类型,可以利用 reindex API,重建索引
原因:
如果修改了字段的数据类型,会导致已被索引的数据无法被搜索
但是如果是增加新的字段,就不会有这样的影响
测试:
PUT /user
{"mappings": {"dynamic": "strict","properties": {"name": {"type": "text"},"address": {"type": "object","dynamic": "true"}}}
}
# 插入文档报错,原因为age为新增字段,会抛出异常
PUT /user/_doc/1
{"name":"cxf","age":32,"address":{"province":"湖南","city":"长沙"}
}
dynamic设置成strict,新增age字段导致文档插入失败

# 修改dynamic后再次插入文档成功
#修改daynamic
PUT /user/_mapping
{"dynamic":true
}
# 添加新的字段映射
# 解释:index:false,默认所有的字段的index都是true,为false是不会被索引的不会被查出来,也就是相当于一个冗余字段。
PUT /my-index/_mapping
{"properties": {"employee-id": {"type": "keyword","index": false}}
}
(6)对已有字段的mapping修改
具体方法:
1)如果要推倒现有的映射, 你得重新建立一个静态索引
2)然后把之前索引里的数据导入到新的索引里
3)删除原创建的索引
4)为新索引起个别名, 为原索引名
PUT /user2
{"mappings": {"properties": {"name": {"type": "text"},"address": {"type": "text","analyzer": "ik_max_word"}}}
}POST _reindex
{"source": {"index": "user"},"dest": {"index": "user2"}
}DELETE /userPUT /user2/_alias/userGET /user
注意: 通过这几个步骤就实现了索引的平滑过渡,并且是零停机
也可以使用条件:

(7)常用Mapping参数配置
(7.1)index
index: 控制当前字段是否被索引,默认为true。如果设置为false,该字段不可被搜索
DELETE /user
PUT /user
{"mappings" : {"properties" : {"address" : {"type" : "text","index": false},"age" : {"type" : "long"},"name" : {"type" : "text"}}}
}PUT /user/_doc/1
{"name":"cxf","address":"广州白云山公园","age":30
}GET /userGET /user/_search
{"query": {"match": {"address": "广州"}}
}

(7.2)index_options
有四种不同基本的index options配置,控制倒排索引记录的内容:
docs : 记录doc id
freqs:记录doc id 和term frequencies(词频)
positions: 记录doc id / term frequencies / term position
offsets: doc id / term frequencies / term posistion / character offsets
text类型默认记录postions,其他默认为 docs。记录内容越多,占用存储空间越大
DELETE /user
PUT /user
{"mappings" : {"properties" : {"address" : {"type" : "text","index_options": "offsets"},"age" : {"type" : "long"},"name" : {"type" : "text"}}}
}
(7.3)null_value
null_value: 需要对Null值进行搜索,只有keyword类型支持设计Null_Value
DELETE /user
PUT /user
{"mappings" : {"properties" : {"address" : {"type" : "keyword","null_value": "NULL"},"age" : {"type" : "long"},"name" : {"type" : "text"}}}
}PUT /user/_doc/1
{"name":"fox","age":32,"address":null
}GET /user/_search
{"query": {"match": {"address": "NULL"}}
}

(7.4)copy_to
copy_to设置:将字段的数值拷贝到目标字段,满足一些特定的搜索需求。copy_to的目标字段不出现在_source中。
# 设置copy_to
DELETE /address
PUT /address
{"mappings" : {"properties" : {"province" : {"type" : "keyword","copy_to": "full_address"},"city" : {"type" : "text","copy_to": "full_address"}}},"settings" : {"index" : {"analysis.analyzer.default.type": "ik_max_word"}}
}PUT /address/_bulk
{ "index": { "_id": "1"} }
{"province": "湖南","city": "长沙"}
{ "index": { "_id": "2"} }
{"province": "湖南","city": "常德"}
{ "index": { "_id": "3"} }
{"province": "广东","city": "广州"}
{ "index": { "_id": "4"} }
{"province": "湖南","city": "邵阳"}GET /address/_search
{"query": {"match": {"full_address": {"query": "湖南常德","operator": "and"}}}
}
(8)Index Template
Index Templates可以帮助你设定Mappings和Settings,并按照一定的规则,自动匹配到新创建的索引之上
模版仅在一个索引被新创建时,才会产生作用。修改模版不会影响已创建的索引
你可以设定多个索引模版,这些设置会被“merge”在一起
你可以指定“order”的数值,控制“merging”的过程
PUT /_template/template_default
{"index_patterns": ["*"],"order": 0,"version": 1,"settings": {"number_of_shards": 1,"number_of_replicas": 1}
}PUT /_template/template_test
{"index_patterns": ["test*"],"order": 1,"settings": {"number_of_shards": 2,"number_of_replicas": 1},"mappings": {"date_detection": false,"numeric_detection": true}
}
(9)lndex Template的工作方式
当一个索引被新创建时:
应用Elasticsearch 默认的settings 和mappings
应用order数值低的lndex Template 中的设定
应用order高的 Index Template 中的设定,之前的设定会被覆盖
应用创建索引时,用户所指定的Settings和 Mappings,并覆盖之前模版中的设定
#查看template信息
GET /_template/template_default
GET /_template/temp*PUT /testtemplate/_doc/1
{"orderNo": 1,"createDate": "2022/01/01"
}
GET /testtemplate/_mapping
GET /testtemplate/_settingsPUT /testmy
{"mappings": {"date_detection": true}
}PUT /testmy/_doc/1
{"orderNo": 1,"createDate": "2022/01/01"
}GET /testmy/_mapping
(10)Dynamic Template
Dynamic Tempate定义在某个索引的Mapping中。
#Dynaminc Mapping 根据类型和字段名
DELETE my_index
PUT my_index/_doc/1
{"firstName":"Ruan","isVIP":"true"
}GET my_index/_mapping
DELETE my_index
PUT my_index
{"mappings": {"dynamic_templates": [{"strings_as_boolean": {"match_mapping_type": "string","match":"is*","mapping": {"type": "boolean"}}},{"strings_as_keywords": {"match_mapping_type": "string","mapping": {"type": "keyword"}}}]}
}#结合路径
PUT /my_test_index
{"mappings": {"dynamic_templates": [{"full_name":{"path_match": "name.*","path_unmatch": "*.middle","mapping":{"type": "text","copy_to": "full_name"}}}]}
}PUT /my_test_index/_doc/1
{"name":{"first": "John","middle": "Winston","last": "Lennon"}
}GET /my_test_index/_search
{"query": {"match": {"full_name": "John"}}
}
