ES02--倒排索引、索引操作、映射管理、文档CURD
1 倒排索引
# 倒排索引:
对一篇文章内容先进行分词,然后对每个词建立索引 # 正向索引是 文章标题--->文章内容
建立索引: 分词--->文章内容
但由于这样建,若文章内容比较大,就会出现索引爆炸(同个文章的内容文词,对应的文章内容都是一样的)
所以再增加一层
建立索引: 分词--->文章标题 再 文章标题--->文章内容
# eg:ES分词完的索引 大概形式
# 关键字 文章
今天(索引) | (文章1,<2,10>,2) (文章3,<8>,1)
星期天(索引) | (文章2,<12,25,100>,3)
出去玩(索引) | (文章5,<11,24,89>,3)(文章1,<8,19>,2)
# 依次对应:分词出现在哪个文章、出现的位置和出现的次数
2 索引操作
# 索引操作 ---> mysql 数据库的操作
# 新建索引
PUT lqz # 下面settings可不加,默认就是1+1
{
"settings": {
"index":{
"number_of_shards":5, # 5个主分片 默认为1个主分片 创建后不可修改
"number_of_replicas":1 # 默认:每个主分片1个副本 创建后可修改
}
}
}
# 查看索引 返回信息:包含 alias索引别名、mappings索引映射、settings索引配置
GET _all # 查看全部索引
GET lqz # 查看某个索引
# 查看索引配置
GET lqz/_settings # 获取lqz索引的配置信息
GET _all/_settings # 获取所有索引的配置信息
GET _settings
GET lqz,lqz2/_settings # 获取lqz和lqz2索引的配置信息
# 修改索引 一般不太用,只能用来修改副本数量
# 修改索引副本数量为2 注:主分片的数量一开始就要定好!!!
PUT lqz/_settings
{
"number_of_replicas": 2
}
# 副本数量可以改 但有可能会出错
如遇到报错:cluster_block_exception
因为这是由于ES新节点的数据目录data存储空间不足
导致从master主节点接收同步数据的时候失败
此时ES集群为了保护数据,会自动把索引分片index置为只读read-only
PUT _all/_settings
{
"index": {
"blocks": {
"read_only_allow_delete": false
}
}
}
# 删除索引
DELETE lqz
2.2 索引的数据迁移
https://www.cnblogs.com/Ace-suiyuan008/p/9985249.html
https://www.cnblogs.com/gmhappy/p/11864054.html
# Reindex
_reindex会将一个索引的快照数据copy到另一个索引
但是并不会复制原索引的mapping(映射)、shard(分片)、replicas(副本)等配置信息
# 默认情况下:
存在相同的_id会进行覆盖 (一般不会发生,除非是将两个索引的数据copy到一个索引中)
# 应用场景:
1.当数据量过大,而索引最初创建的分片数量不足,导致数据入库较慢的情况,
此时需要扩大分片的数量,此时可以尝试使用Reindex
2.当数据的mapping需要修改,但是大量的数据已经导入到索引中了,重新导入数据到新的索引太耗时;
但是在ES中,一个字段的mapping在定义并且导入数据之后是不能再修改的,
# 基础实现
POST _reindex
{
"source": {
"index": "old_index"
},
"dest": {
"index": "new_index"
}
}
# 冲突的解决 version_type参数
参数默认值为internal 即当发生冲突后会覆盖之前的document,
当设置为external 则会新生成一个另外的document
POST _reindex
{
"source": {
"index": "old_index"
},
"dest": {
"index": "new_index",
"version_type": "external"
}
}
# 其他内容:详见上面两个博客
3 映射管理
3.1 映射介绍
# 映射(类型)操作 ---> mysql 建表的操作 # 就是定义表的结构,有哪些字段 字段都是什么类型 参数
Mapping是自定义的字段数据类型,同时告诉es如何索引数据及是否可以被搜索
作用:会让索引建立的更加细致和完善
# 版本问题
-5.x中创建的索引可使用多个类型(multiple mapping types)
# 兼容过渡:可继续像以前一样在Elasticsearch 6.x中运行
-6.0.0及以上创建的索引只包含一个类型(mapping type)
-7.0.0中完全删除类型(mapping type)
# 注:索引如果不创建,直接插入文档,会自动创建索引及映射
3.2 字段类型
# 字段的数据类型
# string类型: text、keyword
-keywrods类型 : 关键字 不分词 直接建立倒排索引
-text类型 : 文本 分词 再建立倒排索引
# 数字类型:long、integer、short、byte、double、float # 就是java的数据类型
-byte : int8 -128---127之间 # 正负2^7-1
-short : int16
-integer : int32
-long : int64
-float : 单精度 小数,表示小数范围小
-double : 双精度 小数,表示小数范围大
# 日期类型: date
# 布尔类型: boolean
# binary类型: binary 二进制类型
# 复杂类型: object(实体,对象),nested(列表) # 一般是字典和列表
# geo类型: geo-point、geo-shape(地理位置) # es也可以做地理位置信息
# 专业类型: ip、competion(搜索建议)
3.3 映射参数
# 属性 描述 适合字段类型
store 值为yes表示存储,no表示不存储 默认为no all
index 值为yes表示分析,no表示不分析 默认为true text
null_value 如果字段为空,可以设置一个默认值,比如"NA" all
(传过来为空,不能搜索,na可以搜索)
analyzer 可以设置索引和搜索时用的分析器,默认使用的是standard分析器 all
还可whitespace、simple # 都是英文分析器
include_in_all 默认es为每个文档定义一个特殊域_all all
作用是让每个字段都被搜索到
若想让某个字段不被搜索到,可以设置为false
format 时间格式字符串模式 date
3.4 映射操作
# 6.x版本创建映射 就是创建索引时,增加参数
PUT books
{
"mappings": {
"book":{ # 多一层,指定类型(表)的名字
"properties":{
"title":{
"type":"text",
"analyzer": "ik_max_word"
},
"price":{
"type":"integer"
},
"addr":{
"type":"keyword"
},
"company":{
"properties":{
"name":{"type":"text"},
"company_addr":{"type":"text"},
"employee_count":{"type":"integer"}
}
},
"publish_date":{"type":"date","format":"yyy-MM-dd"}
}
}
}
}
# 7.x版本以后创建映射(类型,表)
PUT books
{
"mappings": {
"properties":{
"title":{
"type":"text",
"analyzer": "ik_max_word"
},
"price":{ "type":"integer" },
"addr":{ "type":"keyword" },
"company":{ # 复杂类型,再一层properties
"properties":{
"name":{"type":"text"},
"company_addr":{"type":"text"},
"employee_count":{"type":"integer"}
}
},
"publish_date":{
"type":"date",
"format":"yyy-MM-dd"
}
}
}
}
# 查看映射
GET books/_mapping # 查看books索引的mapping
GET _all/_mapping # 获取所有索引的mapping
GET _mapping
# 修改映射 可以添加新字段,已有字段不允许修改
1.尾部添加参数:_mapping
# 修改映射: 新增字段hobby
PUT books/_mapping
{
"properties": {
"hobby":{
"type":"text"
}
}
}
# 删除映射 不允许删除
4 文档基本CURD
# 文档操作(json格式的数据) ---> mysql 一行一行数据的操作
# 新增/插入文档 特殊说明索引和映射都不存在,也可以插入文档,会自动创建索引及类型
PUT books/_doc/1 # 类型名没有,默认就是_doc 1表示id号
{
"title":"大头儿子小偷爸爸",
"price":100,
"addr":"北京天安门",
"company":{
"name":"我爱北京天安门",
"company_addr":"我的家在东北松花江傻姑娘",
"employee_count":10
},
"publish_date":"2019-08-19"
}
# 插入文档时,可以不按照映射的类型插入 因为是非关系型数据库
PUT books/_doc/2
{
"title":"白雪公主和十个小矮人",
"price":"99", # 写字符串会自动转换
"addr":"黑暗森里",
"publish_date":"2018-05-19",
"name":"lqz" # 比映射多1个字段
}
# 修改文档两种方式
# 第一种:覆盖修改 直接重写
PUT lqz/_doc/1
{
"name":"顾老二",
"age":30,
"from": "gu",
"desc": "皮肤黑、武器长、性格直",
"tags": ["黑", "长", "直"]
}
# 第二种:局部修改
1.POST请求
2.尾部添加参数:_update
3.修改的内容:在"doc"字典中
POST lqz/_update/1/ # 旧版本:POST lqz/_doc/1/_update
{
"doc": {
"desc": "皮肤很safasdfsda黄,武器很长,性格很直",
"tags": ["很黄","很长", "很直"]
}
}
# 删除文档
DELETE lqz/_doc/4
# 查询文档 简单查询
GET lqz/_doc/1 # 真正数据 在返回的 _source里
# 复杂查询很多操作 ---> es的操作,最重要的就是查询
# es主要使用场景: 搜索功能用
原来数据在mysql中,同步到es中
---> 以后只要mysql新增记录,都同步到es中
---> 搜索的时候,去es中搜索
---> 返回给前端,完成搜索功能