ES_之_基本用法
Github
:https://github.com/HealerJean
一、属性介绍
索引库就类似数据库表,
mapping
映射就类似表的结构,我们要向es
中存储数据,必须先创建“库”和“表”。
1、Mapping
映射属性
1)说明
a、type
type
:字段数据类型,常见的简单类型有:
类型 | 说明 |
---|---|
字符串 | text (可分词的文本) |
keyword (精确值)keyword 类型只能整体搜索,不支持搜索部分内容 |
|
数值 | long、integer、short、byte、double、float、 |
布尔: | boolean |
日期: | date |
对象: | object |
b、index
:
是否创建索引,默认为
true
c、analyzer
:
使用哪种分词器
d、properties
该字段的子字段
2)样例
{
"age": 21,
"weight": 52.1,
"isMarried": false,
"info": "真相只有一个!",
"email": "zy@itcast.cn",
"score": [99.1, 99.5, 98.9],
"name": {
"firstName": "柯",
"lastName": "南"
}
}
字段 | 说明 |
---|---|
age : |
类型为 integer;参与搜索,因此需要index为true;无需分词器 |
weight : |
类型为float;参与搜索,因此需要index为true;无需分词器 |
isMarried : |
类型为boolean;参与搜索,因此需要index为true;无需分词器 |
info : |
类型为字符串,需要分词,因此是text;参与搜索,因此需要index为true;分词器可以用ik_smart |
email : |
类型为字符串,但是不需要分词,因此是keyword;不参与搜索,因此需要index为false;无需分词器 |
score : |
虽然是数组,但是我们只看元素的类型,类型为float;参与搜索,因此需要index为true;无需分词器 |
name : |
类型为object,需要定义多个子属性 |
name.firstName |
类型为字符串,但是不需要分词,因此是keyword;参与搜索,因此需要index为true;无需分词器 |
name.lastName |
类型为字符串,但是不需要分词,因此是keyword;参与搜索,因此需要index为true;无需分词器 |
2、分词器
需要单独安装
问:分词器作用:
答案:创建倒排索引时对文档分词,用户搜索时,对输入的内容分词
问: IK
分词器有几种模式:
答案:ik_smart
:智能切分,粗粒度;ik_max_word
:最细切分,细粒度
二、索引库 CRUD
CRUD简单描述:
- 创建索引库:PUT /索引库名
- 查询索引库:GET /索引库名
- 删除索引库:DELETE /索引库名
- 修改索引库(添加字段):PUT /索引库名/_mapping
1、增 PUT
基本语法:
- 请求方式:
PUT
- 请求路径:/索引库名,可以自定义
- 请求参数:
mapping
映射
PUT /es_log
{
"mappings":{
"properties": {
"modifiedTime": {
"index": true,
"store": true,
"type": "keyword"
},
"nodeSortId": {
"index": true,
"store": true,
"type": "integer"
},
"bizDesc": {
"index": true,
"store": true,
"type": "keyword"
},
"orderId": {
"index": true,
"store": true,
"type": "keyword"
},
"policyNo": {
"index": true,
"store": true,
"type": "keyword"
},
"inValidateTime": {
"index": true,
"store": true,
"type": "keyword"
},
"type": {
"index": true,
"store": true,
"type": "keyword"
},
"uuid": {
"index": true,
"store": true,
"type": "keyword"
},
"customCode": {
"index": true,
"store": true,
"type": "keyword"
},
"node": {
"index": true,
"store": true,
"type": "keyword"
},
"customType": {
"index": true,
"store": true,
"type": "keyword"
},
"insuranceId": {
"index": true,
"store": true,
"type": "keyword"
},
"createdTime": {
"index": true,
"store": true,
"type": "keyword"
},
"bizData": {
"index": true,
"store": true,
"type": "keyword"
},
"traceSortId": {
"index": true,
"store": true,
"type": "integer"
}
}
}
}
2、查 GET
基本语法:
- 请求方式:GET
- 请求路径:/索引库名
- 请求参数:无
GET /索引库名
{
"es_log" : {
"aliases" : { },
"mappings" : {
"properties" : {
"bizData" : {
"type" : "keyword",
"store" : true
},
"bizDesc" : {
"type" : "keyword",
"store" : true
},
"createdTime" : {
"type" : "keyword",
"store" : true
},
"customCode" : {
"type" : "keyword",
"store" : true
},
"customType" : {
"type" : "keyword",
"store" : true
},
"inValidateTime" : {
"type" : "keyword",
"store" : true
},
"insuranceId" : {
"type" : "keyword",
"store" : true
},
"modifiedTime" : {
"type" : "keyword",
"store" : true
},
"node" : {
"type" : "keyword",
"store" : true
},
"nodeSortId" : {
"type" : "integer",
"store" : true
},
"orderId" : {
"type" : "keyword",
"store" : true
},
"policyNo" : {
"type" : "keyword",
"store" : true
},
"traceSortId" : {
"type" : "integer",
"store" : true
},
"type" : {
"type" : "keyword",
"store" : true
},
"uuid" : {
"type" : "keyword",
"store" : true
}
}
},
"settings" : {
"index" : {
"routing" : {
"allocation" : {
"include" : {
"_tier_preference" : "data_content"
}
}
},
"number_of_shards" : "1",
"provided_name" : "es_log",
"creation_date" : "1714124877672",
"number_of_replicas" : "1",
"uuid" : "yhP-OiJ8RMOKs421Bqu2Dg",
"version" : {
"created" : "8020299"
}
}
}
}
}
3、修改索引库 PUT
说明:这里的修改是只能增加新的字段到
mapping
中。倒排索引结构虽然不复杂,但是一旦数据结构改变(比如改变了分词器),就需要重新创建倒排索引,这简直是灾难。因此索引库一旦创建,无法修改
mapping
。虽然无法修改mapping
中已有的字段,但是却允许添加新的字段到mapping
中,因为不会对倒排索引产生影响。
PUT /索引库名/_mapping
{
"properties": {
"新字段名":{
"type": "integer"
}
}
}
4、 删除索引库 DELETE
语法:
- 请求方式:DELETE
- 请求路径:/索引库名
- 请求参数:无
DELETE /es_log
三、文档 CRUD
1、增 PUT
,POST
1)创建一个索引
第一个命令使用
PUT
方法创建名为animal
的索引。在调用的末尾附加pretty
命令,就可以打印友好JSON
响应。
入参:
PUT /animal?pretty
出参:
{
"acknowledged" : true,
"shards_acknowledged" : true,
"index" : "animal"
}
2)创建单个文档
1、
animal
是文档的所在索引,_doc
是类型,1
是我们手工指定id
,如果不指定,那就要用POST
方法,ES
会为我们自动分配。
入参:
PUT /animal/_doc/1
{
"name":"熊猫",
"weight":"500kg",
"zoo":"北京动物园"
}
出参:
{
"_index" : "animal",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
3)创建多个文档
入参:
PUT /animal/_doc/1
{
"name":"熊猫100",
"weight":"500kg",
"zoo":"北京动物园"
}
PUT /animal/_doc/2
{
"name":"老虎100",
"weight":"300kg",
"zoo":"北京动物园"
}
PUT /animal/_doc/3
{
"name":"狮子100",
"weight":"500kg",
"zoo":"上海动物园"
}
PUT /animal/_doc/4
{
"name":"孔雀100",
"weight":"100kg",
"zoo":"南京动物园"
}
PUT /animal/_doc/5
{
"name":"鳄鱼100",
"weight":"400kg",
"zoo":"河北动物园"
}
出参:
# PUT /animal/_doc/1
{
"_index" : "animal",
"_id" : "1",
"_version" : 4,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 11,
"_primary_term" : 1
}
# PUT /animal/_doc/2
{
"_index" : "animal",
"_id" : "2",
"_version" : 3,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 12,
"_primary_term" : 1
}
# PUT /animal/_doc/3
{
"_index" : "animal",
"_id" : "3",
"_version" : 3,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 13,
"_primary_term" : 1
}
# PUT /animal/_doc/4
{
"_index" : "animal",
"_id" : "4",
"_version" : 3,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 14,
"_primary_term" : 1
}
# PUT /animal/_doc/5
{
"_index" : "animal",
"_id" : "5",
"_version" : 3,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 15,
"_primary_term" : 1
}
2、查 GET
key | 说明 |
---|---|
_index |
文档所属索引名称 |
_type |
文档所属类型名 |
_id |
文档唯一 ID |
_score |
文档相关性打分 |
_source |
文档 JSON 数据 |
_version |
文档版本信息 |
1)根据 Id
查询文档
入参:
GET /animal/_doc/1
出参:
{
"_index" : "animal",
"_id" : "1",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"name" : "熊猫",
"weight" : "500kg",
"zoo" : "北京动物园"
}
}
2)查询全部数据
入参:
GET animal/_search
出参:
{
"took" : 66,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 5,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "animal",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"name" : "熊猫100",
"weight" : "500kg",
"zoo" : "北京动物园"
}
},
{
"_index" : "animal",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"name" : "老虎100",
"weight" : "300kg",
"zoo" : "北京动物园"
}
},
{
"_index" : "animal",
"_id" : "3",
"_score" : 1.0,
"_source" : {
"name" : "狮子100",
"weight" : "500kg",
"zoo" : "上海动物园"
}
},
{
"_index" : "animal",
"_id" : "4",
"_score" : 1.0,
"_source" : {
"name" : "孔雀100",
"weight" : "100kg",
"zoo" : "南京动物园"
}
},
{
"_index" : "animal",
"_id" : "5",
"_score" : 1.0,
"_source" : {
"name" : "鳄鱼100",
"weight" : "400kg",
"zoo" : "河北动物园"
}
}
]
}
}
3)不指定字段查询
查询结果有很多记录,这是因为动物的名字里都带有
100
入参:
GET animal/_search
{
"query":{
"query_string":{
"query":"100"
}
}
}
出参:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 5,
"relation" : "eq"
},
"max_score" : 0.09844007,
"hits" : [
{
"_index" : "animal",
"_id" : "1",
"_score" : 0.09844007,
"_source" : {
"name" : "熊猫100",
"weight" : "500kg",
"zoo" : "北京动物园"
}
},
{
"_index" : "animal",
"_id" : "2",
"_score" : 0.09844007,
"_source" : {
"name" : "老虎100",
"weight" : "300kg",
"zoo" : "北京动物园"
}
},
{
"_index" : "animal",
"_id" : "3",
"_score" : 0.09844007,
"_source" : {
"name" : "狮子100",
"weight" : "500kg",
"zoo" : "上海动物园"
}
},
{
"_index" : "animal",
"_id" : "4",
"_score" : 0.09844007,
"_source" : {
"name" : "孔雀100",
"weight" : "100kg",
"zoo" : "南京动物园"
}
},
{
"_index" : "animal",
"_id" : "5",
"_score" : 0.09844007,
"_source" : {
"name" : "鳄鱼100",
"weight" : "400kg",
"zoo" : "河北动物园"
}
}
]
}
}
4)指定字段查询
入参:
GET animal/_search
{
"query":{
"query_string":{
"query":"100kg",
"fields": ["weight"]
}
}
}
出参:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.5198257,
"hits" : [
{
"_index" : "animal",
"_id" : "4",
"_score" : 1.5198257,
"_source" : {
"name" : "孔雀100",
"weight" : "100kg",
"zoo" : "南京动物园"
}
}
]
}
}
3、删 DELETE
1)删除文档
入参:
DELETE /animal/_doc/1
出参:
{
"_index" : "animal",
"_id" : "1",
"_version" : 5,
"result" : "deleted",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 16,
"_primary_term" : 1
}
4、更 PUT
Elasticsearch
提供近实时的数据操作和搜索功能。默认情况 下,从索引、更新、删除数据到在搜索结果中显示数据,会有少于1s 的延迟(刷新间隔)。这是与其他平台(如SQL
)的一个重要区别, 在SQL
中,数据在事务完成后立即可用
1)覆盖文档
animal
是文档的所在索引,_doc
是类型,1
是我们手工指定id
,如果不指定,那就要用POST
方法,ES
会为我们自动分配。
a、回顾创建单个文档
入参:
PUT /animal/_doc/1
{
"name":"熊猫",
"weight":"500kg",
"zoo":"北京动物园"
}
出参:
{
"_index" : "animal",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
b、修改文档
ID
为1
。如果用不同的(或相同的)文档再次执行上述命令,那么Elasticsearch
将在现有文档的基础上替换(即重新索引)一个ID
为1
的新文档:
入参:
PUT /animal/_doc/1
{
"name":"熊猫修改",
"weight":"500kg",
"zoo":"北京动物园"
}
2)更新文档 _update
Elasticsearch
除了能够索引和替换文档外,还可以更新文档。⬤
Elasticsearch
实际上并不是进行就地更新,每当进行更新时,Elasticsearch
会删除旧文档,然后索引一个新文档,但这对用户来 说是一次调用。⬤ 实际上
Elasticsearch
的数据存储结构决定了其不能 像关系数据库那样进行字段级的更新,所有的更新都是先删除旧文 档,再插入一条新文档,但这个过程对用户来说是透明的
a、修改文档
修改
Id
为1
的name
注意点:
⬤ 路径
_update
⬤ ` _doc ` 变成
doc
POST /animal/_update/1?pretty
{
"doc": {
"name": "熊猫update"
}
}
b、修改文档并新增字段
POST /animal/_update/1?pretty
{
"doc": {
"name": "熊猫update",
"age":10
}
}
5、批量操作 _bulk
除了能够索引、更新和删除单个文档外,
Elasticsearch
还提供 了使用批量API批量执行上述任何操作的功能。此功能非常重要,因 为它提供了一种非常有效的机制,可以以尽可能少的网络往返时间尽 可能快速地执行多个操作
1)注意事项
1、批量 API
不会由于其中一个操作失败而失败。如果一个操作由于 某个原因失败,它将继续处理后面的其余操作。当批量 API
返回时, 它将为每个操作提供一个状态(以相同的发送顺序),以便用户检查 特定操作是否失败。
2、对于删除操作,并不会立即删除对应的源文档,因为删除只需要删除文档的 ID
。在 Elasticsearch
中,删除操作只是把需要删除的文档的 ID
记录到了一个列表中,当段合并时才有可能真正把源文档删除。