Loading

03_ElasticSearch基本使用

cat API:

/_cat/allocation #查看单节点的shard分配整体情况
/_cat/shards #查看各shard的详细情况
/_cat/shards/{index} #查看指定分片的详细情况
/_cat/master #查看master节点信息
/_cat/nodes #查看所有节点信息
/_cat/indices #查看集群中所有index的详细信息
/_cat/indices/{index} #查看集群中指定index的详细信息
/_cat/segments #查看各index的segment详细信息,包括segment名, 所属shard, 内存(磁盘)占用大小, 是否刷盘
/_cat/segments/{index}#查看指定index的segment详细信息
/_cat/count #查看当前集群的doc数量
/_cat/count/{index} #查看指定索引的doc数量
/_cat/recovery #查看集群内每个shard的recovery过程.调整replica。
/_cat/recovery/{index}#查看指定索引shard的recovery过程
/_cat/health #查看集群当前状态:红、黄、绿
/_cat/pending_tasks #查看当前集群的pending task
/_cat/aliases #查看集群中所有alias信息,路由配置等
/_cat/aliases/{alias} #查看指定索引的alias信息
/_cat/thread_pool #查看集群各节点内部不同类型的threadpool的统计信息,
/_cat/plugins #查看集群各个节点上的plugin信息
/_cat/fielddata #查看当前集群各个节点的fielddata内存使用情况
/_cat/fielddata/{fields} #查看指定field的内存使用情况,里面传field属性对应的值
/_cat/nodeattrs #查看单节点的自定义属性
/_cat/repositories #输出集群中注册快照存储库
/_cat/templates #输出当前正在存在的模板信息

Elasticsearch安装分词插件

Elasticsearch提供插件机制对系统进行扩展,以安装analysis-icu这个分词插件为例

在线安装

#查看已安装插件
bin/elasticsearch‐plugin list
#安装插件
bin/elasticsearch‐plugin install analysis‐icu
#删除插件
bin/elasticsearch‐plugin remove analysis‐icu
注意:安装和删除完插件后,需要重启ES服务才能生效。
测试分词效果
# unicode支持,中文分词良好
POST _analyze
{
    "analyzer":"icu_analyzer",
    "text":"中华人民共和国"
}

离线安装

本地下载相应的插件,解压,然后手动上传到elasticsearch的plugins目录,然后重启ES实例就可以了。
上传本地文件到服务器:
# 创建目录
mkdir -p /opt/ik
# 上传文件到服务器
scp D:/develop/elasticsearch-analysis-ik-7.17.7.zip root@192.168.211.156:/opt
# 解压到该目录
unzip -d /opt/ik/ elasticsearch-analysis-ik-7.17.7.zip

# 复制到ES插件目录下
docker cp /opt/ik ElasticSearch:/usr/share/elasticsearch/plugins/ik
# 重启容器
docker stop ElasticSearch
docker start ElasticSearch

注意:ik分词版本要与es版本保持一致,若不一致则需要修改分词器配置文件中的版本信息:

# 修改配置文件
vim plugin-descriptor.properties
# 修改为你当前的es版本
elasticsearch.version=7.17.10
测试分词效果
# unicode支持,中文分词良好
POST _analyze
{
    "analyzer":"icu_analyzer",
    "text":"中华人民共和国"
}

#ES的默认分词设置是standard,会单字拆分
POST _analyze
{
    "analyzer":"standard",
    "text":"中华人民共和国"
}

#ik_smart:会做最粗粒度的拆
POST _analyze
{
    "analyzer": "ik_smart",
    "text": "中华人民共和国"
}

#ik_max_word:会将文本做最细粒度的拆分
POST _analyze
{
    "analyzer":"ik_max_word",
    "text":"中华人民共和国"
}

分词结果:

 

扩展ik分词器分词词条:

# 配置扩展词条,分词器的配置文件
vim /usr/local/docker/volumes/ik/config/IKAnalyzer.cfg.xml

# 新增自定义词条
vim my-custom.dic

# 增加分词词条
芝士
芝士蛋糕

# 重启容器
docker stop ElasticSearch
docker start ElasticSearch

 配置自定义扩展词条前:

 配置自定义扩展词条后:

创建索引时可以指定IK分词器作为默认分词器:
PUT /es_db
{
    "settings": {
        "index": {
            "analysis.analyzer.default.type": "ik_max_word"
        }
    }
}

ElasticSearch基本概念

关系型数据库 VS ElasticSearch

  在7.0之前,一个 Index可以设置多个Types
  目前Type已经被Deprecated,7.0开始,一个索引只能创建一个Type -“_doc”
  传统关系型数据库和Elasticsearch的区别:
    Elasticsearch- Schemaless /相关性/高性能全文检索
    RDMS —事务性/ Join

索引(Index)

一个索引就是一个拥有几分相似特征的文档的集合。比如说,可以有一个客户数据的索引,另一个产品目录的索引,还有一个订单数据的索引。
一个索引由一个名字来标识(必须全部是小写字母的),并且当我们要对对应于这个索引中的文档进行索引、搜索、更新和删除的时候,都要使用到这个名字。

文档(Document)

Elasticsearch是面向文档的,文档是所有可搜索数据的最小单位。
  日志文件中的日志项
  一本电影的具体信息/一张唱片的详细信息
  MP3播放器里的一首歌/一篇PDF文档中的具体内容
文档会被序列化成JSON格式,保存在Elasticsearch中
  JSON对象由字段组成
  每个字段都有对应的字段类型(字符串/数值/布尔/日期/二进制/范围类型)
每个文档都有一个Unique ID
  可以自己指定ID或者通过Elasticsearch自动生成
一篇文档包含了一系列字段,类似数据库表中的一条记录
JSON文档,格式灵活,不需要预先定义格式
  字段的类型可以指定或者通过Elasticsearch自动推算
  支持数组/支持嵌套

文档元数据

元数据,用于标注文档的相关信息:
_index:文档所属的索引名
_type:文档所属的类型名
_id:文档唯—ld
_source: 文档的原始Json数据
_version: 文档的版本号,修改删除操作_version都会自增1
_seq_no: 和_version一样,一旦数据发生更改,数据也一直是累计的。Shard级别严格递增,保证后写入的Doc的_seq_no大于先写入的Doc的_seq_no。
_primary_term: _primary_term主要是用来恢复数据时处理当多个文档的
_seq_no一样时的冲突,避免Primary Shard上的写入被覆盖。每当Primary Shard发生重新分配时,比如重启,Primary选举等,_primary_term会递增1。 

ElasticSearch索引操作

创建索引

索引命名必须小写,不能以下划线开头
格式: 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
    }
}

查询索引

格式: GET /索引名称 
#查询索引
GET /es_db

#es_db是否存在
HEAD /es_db

删除索引

格式: DELETE /索引名称
DELETE /es_db

ElasticSearch文档操作

示例数据 
PUT /es_db
{
    "settings": {
        "index": {
            "analysis.analyzer.default.type": "ik_max_word"
        }
    }
}

PUT /es_db/_doc/1
{
    "name": "张三",
    "sex": 1,
    "age": 25,
    "address": "广州天河公园",
    "remark": "java developer"
}

PUT /es_db/_doc/2
{
    "name": "李四",
    "sex": 1,
    "age": 28,
    "address": "广州荔湾大厦",
    "remark": "java assistant"
}

PUT /es_db/_doc/3
{
    "name": "王五",
    "sex": 0,
    "age": 26,
    "address": "广州白云山公园",
    "remark": "php developer"
}

PUT /es_db/_doc/4
{
    "name": "赵六",
    "sex": 0,
    "age": 22,
    "address": "长沙橘子洲",
    "remark": "python assistant"
}

PUT /es_db/_doc/5
{
    "name": "张龙",
    "sex": 0,
    "age": 19,
    "address": "长沙麓谷企业广场",
    "remark": "java architect assistant"
}

PUT /es_db/_doc/6
{
    "name": "赵虎",
    "sex": 1,
    "age": 32,
    "address": "长沙麓谷兴工国际产业园",
    "remark": "java architect"
}

添加(索引)文档

格式: [PUT | POST] /索引名称/[_doc | _create ]/id
# 创建文档,指定id
# 如果id不存在,创建新的文档,否则先删除现有文档,再创建新的文档,版本会增加
PUT /es_db/_doc/1
{
    "name": "张三",
    "sex": 1,
    "age": 25,
    "address": "广州天河公园",
    "remark": "java developer"
}

#创建文档,ES生成id
POST /es_db/_doc
{
    "name": "张三",
    "sex": 1,
    "age": 25,
    "address": "广州天河公园",
    "remark": "java developer"
}
注意:POST和PUT都能起到创建/更新的作用,PUT需要对一个具体的资源进行操作也就是要确定id才能进行更新/创建,而POST是可以针对整个资源集合进行操作的,如果不写id就由ES生成一个唯一id进行创建新文档,如果填了id那就针对这个id的文档进行创建/更新。

Create -如果ID已经存在,会失败:
PUT /es_db/_create/1
{
    "name": "张三",
    "sex": 1,
    "age": 66,
    "address": "广州天河公园",
    "remark": "java developer"
}

修改文档

全量更新,整个json都会替换,格式: [PUT | POST] /索引名称/_doc/id
如果文档存在,现有文档会被删除,新的文档会被索引
# 全量更新,替换整个json
PUT /es_db/_doc/1/
{
    "name": "张三",
    "sex": 1,
    "age": 25
}

#查询文档
GET /es_db/_doc/1

使用_update部分更新,格式: POST /索引名称/_update/id
update不会删除原来的文档,而是实现真正的数据更新
# 部分更新:在原有文档上更新
# Update ‐文档必须已经存在,更新只会对相应字段做增量修改
POST /es_db/_update/1
{
    "doc": {
        "age": 28
    }
}

#查询文档
GET /es_db/_doc/1

使用 _update_by_query 更新文档 
POST /es_db/_update_by_query
{
    "query": {
        "match": {
            "_id": 1
        }
    },
    "script": {
        "source": "ctx._source.age = 30"
    }
}

GET /es_db/_doc/1

并发场景下修改文档

_seq_no和_primary_term是对_version的优化,7.X版本的ES默认使用这种方式控制版本,所以当在高并发环境下使用乐观锁机制修改文档时,要带上当前文档的_seq_no和_primary_term进行更新: 
POST /es_db/_doc/2?if_seq_no=2&if_primary_term=2
{
    "name": "李四xxx"
}

GET /es_db/_doc/1
如果版本号不对,会抛出版本冲突异常,如下图: 

查询文档

根据id查询文档,格式: GET /索引名称/_doc/id
GET /es_db/_doc/1
条件查询 _search,格式: /索引名称/_doc/_search
# 查询前10条文档
GET /es_db/_doc/_search
ES Search API提供了两种条件查询搜索方式:
REST风格的请求URI,直接将参数带过去
封装到request body中,这种方式可以定义更加易读的JSON格式
#通过URI搜索,使用“q”指定查询字符串,“query string syntax” KV键值对

#条件查询, 如要查询age等于28岁的 _search?q=*:***
GET /es_db/_doc/_search?q=age:28

#范围查询, 如要查询age在25至26岁之间的 _search?q=***[** TO **] 注意: TO 必须为大写
GET /es_db/_doc/_search?q=age[25 TO 26]

#查询年龄小于等于28岁的 :<=
GET /es_db/_doc/_search?q=age:<=28
#查询年龄大于28前的 :>
GET /es_db/_doc/_search?q=age:>28

#分页查询 from=*&size=*
GET /es_db/_doc/_search?q=age[25 TO 26]&from=0&size=1

#对查询结果只输出某些字段 _source=字段,字段
GET /es_db/_doc/_search?_source=name,age

#对查询结果排序 sort=字段:desc/asc
GET /es_db/_doc/_search?sort=age:desc
通过请求体的搜索方式会在后面详细讲解(DSL)
GET /es_db/_search
{
    "query": {
        "match": {
            "address": "广州白云"
        }
    }
}

删除文档

格式: DELETE /索引名称/_doc/id 
DELETE /es_db/_doc/1

ElasticSearch文档批量操作

批量操作可以减少网络连接所产生的开销,提升性能:
  支持在一次API调用中,对不同的索引进行操作
  可以在URI中指定Index,也可以在请求的Payload中进行
  操作中单条操作失败,并不会影响其他操作
  返回结果包括了每一条操作执行的结果

批量写入

批量对文档进行写操作是通过_bulk的API来实现的
请求方式:POST
请求地址:_bulk
请求参数:通过_bulk操作文档,一般至少有两行参数(或偶数行参数)
  第一行参数为指定操作的类型及操作的对象(index,type和id)
  第二行参数才是操作的数据
参数类似于: 
{"actionName":{"_index":"indexName", "_type":"typeName","_id":"id"}}
{"field1":"value1", "field2":"value2"}
actionName:表示操作类型,主要有create,index,delete和update

批量创建文档create 

POST _bulk
{"create":{"_index":"article", "_type":"_doc", "_id":3}}
{"id":3,"title":"yyj老师","content":"yyj老师666","tags":["java", "面向对象"],"create_time":1554015482530}
{"create":{"_index":"article", "_type":"_doc", "_id":4}}
{"id":4,"title":"yyj2老师","content":"yyj2老师NB","tags":["java", "面向对象"],"create_time":1554015482530}

普通创建或全量替换index

POST _bulk
{"index":{"_index":"article", "_type":"_doc", "_id":3}}
{"id":3,"title":"yyj老师","content":"yyj老师666","tags":["java", "面向对象"],"create_time":1554015482530}
{"index":{"_index":"article", "_type":"_doc", "_id":4}}
{"id":4,"title":"yyj2老师","content":"yyj2老师NB","tags":["java", "面向对象"],"create_time":1554015482530}

如果原文档不存在,则是创建
如果原文档存在,则是替换(全量修改原文档)

批量删除delete

POST _bulk
{"delete":{"_index":"article", "_type":"_doc", "_id":3}}
{"delete":{"_index":"article", "_type":"_doc", "_id":4}}

批量修改update

POST _bulk
{"update":{"_index":"article", "_type":"_doc", "_id":3}}
{"doc":{"title":"ES大法必修内功"}}
{"update":{"_index":"article", "_type":"_doc", "_id":4}}
{"doc":{"create_time":1554018421008}}

组合应用

POST _bulk
{"create":{"_index":"article", "_type":"_doc", "_id":3}}
{"id":3,"title":"yyj老师","content":"yyj老师666","tags":["java", "面向对象"],"create_time":1554015482530}
{"delete":{"_index":"article", "_type":"_doc", "_id":3}}
{"update":{"_index":"article", "_type":"_doc", "_id":4}}
{"doc":{"create_time":1554018421008}}

批量读取

es的批量查询可以使用mget和msearch两种。其中mget是需要我们知道它的id,可以指定不同的index,也可以指定返回值source。msearch可以通过字段查询来进行一个批量的查找。

_mget

#可以通过ID批量获取不同index和type的数据
GET _mget
{
    "docs": [{
            "_index": "es_db",
            "_id": 1
        },
        {
            "_index": "article",
            "_id": 4
        }
    ]
}

#可以通过ID批量获取es_db的数据
GET /es_db/_mget
{
    "docs": [{
            "_id": 1
        },
        {
            "_id": 4
        }
    ]
}
#简化后
GET /es_db/_mget
{
    "ids": ["1", "2"]
}

_msearch

在_msearch中,请求格式和bulk类似。查询一条数据需要两个对象,第一个设置index和type,第二个设置查询语句。查询语句和search相同。如果只是查询一个index,我们可以在url中带上index,这样,如果查该index可以直接用空对象表示。 
GET /es_db/_msearch
{}
{"query" : {"match_all" : {}}, "from" : 0, "size" : 2}
{"index" : "article"}
{"query" : {"match_all" : {}}}

 

posted @ 2023-06-23 16:37  1640808365  阅读(39)  评论(0编辑  收藏  举报