在前面我们对ES的一些基本的概念已经有了充分的了解了。接下来就可以学习ES的各种增删改查操作了,首先我们要学习的是索引库的操作。
Index就类似数据库表,Mapping映射就类似表的结构(约束)。我们要向es中存储数据,必须先创建Index和Mapping
目录
一、Mapping映射属性
Mapping是对索引库中文档的约束,常见的Mapping属性包括:
1.1 type
-
type:字段数据类型,常见的简单类型有:
-
字符串:
text
(可分词的文本)、keyword
(精确值,例如:品牌、国家、ip地址) -
数值:
long
、integer
、short
、byte
、double
、float
、 -
布尔:
boolean
-
日期:
date
-
对象:
object
-
1.2 index
-
index
:是否创建索引,默认为true
注意:如果index值为true,es就会给这个字段创建倒排索引,将来就可以根据这个字段做搜索排序了。反之设置为了false,这个字段就不会创建索引,将来就没有办法根据这个字段去做搜索或者排序。这个是大家特别要注意的。
1.3 analyzer
analyzer
:使用哪种分词器(只有text类型需要做分词的)
1.4 properties
properties
:该字段的子字段(也就是json对象里面又嵌套了json对象)
例如下面的json文档:
{
"age": 21,
"weight": 52.1,
"isMarried": false,
"info": "Java程序员都是最棒的",
"email": "zy@itcast.cn",
"score": [99.1, 99.5, 98.9],
"name": {
"firstName": "云",
"lastName": "赵"
}
}
对应的每个字段映射(Mapping):
字段名 | 字段类型 | 类型说明 | 是否 参与搜索 | 是否 参与分词 | 分词器 | |
---|---|---|---|---|---|---|
age |
| 整数 | 是 | 否 | 无 | |
weight |
| 浮点数 | 是 | 否 | 无 | |
isMarried |
| 布尔 | 是 | 否 | 无 | |
info |
| 字符串,但需要分词 | 是 | 是 | IK | |
|
| 字符串,但是不分词 | 否 | 否 | 无 | |
score |
| 只看数组中元素类型 | 是 | 否 | 无 | |
name | firstName |
| 字符串,但是不分词 | 是 | 否 | 无 |
lastName |
| 字符串,但是不分词 | 是 | 否 | 无 |
相信大家在看到一个json文档的时候应该能够自己分析出它们对应的mapping映射的属性了,但是我们将来在创建索引库的时候,这些属性应该怎么指定,语法是什么呢
二、索引库操作
2.1 索引库的CRUD
由于Elasticsearch采用的是Restful风格的API,因此其请求方式和路径相对都比较规范,而且请求参数也都采用JSON风格。
我们直接基于Kibana的DevTools来编写请求做测试,由于有语法提示,会非常方便。
2.1.1 创建索引库和映射
1)基本语法:
-
请求方式:
PUT
-
请求路径:
/索引库名
,可以自定义 -
请求参数:
mapping
映射
2)格式:
PUT /索引库名称
{
"mappings": {
"properties": {
"字段名":{
"type": "text",
"analyzer": "ik_smart"
},
"字段名2":{
"type": "keyword",
"index": "false"
},
"字段名3":{
"properties": {
"子字段": {
"type": "keyword"
}
}
},
// ...略
}
}
}
3)示例:
# PUT /users
{
"mappings": {
"properties": {
"info":{
"type": "text",
"analyzer": "ik_smart"
},
"email":{
"type": "keyword",
"index": "false"
},
"name":{
"properties": {
"firstName": {
"type": "keyword"
}
}
}
}
}
}
4)实战演练:
打开kibana的开发者工具
右侧运行结果为 acknowledged:true 则表示创建索引库成功
2.1.2 查询索引库
1)基本语法:
-
请求方式:GET
-
请求路径:/索引库名
-
请求参数:无
2)格式:
GET /索引库名
3)示例:
GET /user
4)实战演练:
2.1.3 修改索引库
ES的索引库是不支持修改的。假如现在有一个索引库已经创建好了,已经向里面导入了成千上万,甚至说一亿的数据,里面的字段分词以及倒排索引都创建好了。然后现在说要修改这个库,把有索引的字段变成没有索引,把另一个没有索引的字段改成有索引,那之前创建的倒排索引做的分词词库是不是全部作废了,而且还要重新再去分词,对于整个数据库的影响是比较大的。
倒排索引结构虽然不复杂,但是一旦数据结构改变(比如改变了分词器),就需要重新创建倒排索引,这简直是灾难。因此索引库一旦创建,无法修改mapping。
虽然无法修改mapping中已有的字段,但是却允许添加新的字段到mapping中,因为不会对倒排索引产生影响。因此修改索引库能做的就是向索引库中添加新字段,或者更新索引库的基础属性。
1)语法说明:
PUT /索引库名/_mapping
{
"properties": {
"新字段名":{
"type": "integer"
}
}
}
2)示例:
PUT /user/_mapping
{
"properties": {
"age":{
"type": "integer"
}
}
}
3)实战演练:
我们可以先修改一下已有的字段,发现无法修改。
报错信息:非法参数错误,info字段的类型不能够从text修改为keyword
现在我们添加一个性别字段,发现就可以添加成功
再查一下,就可以发向添加进去了
2.1.4 删除索引库
1)语法:
-
请求方式:DELETE
-
请求路径:/索引库名
-
请求参数:无
2)格式:
DELETE /索引库名
3)示例:
DELETE /user
4)实战演练:
删除之后再查询就会发向返回了404,因为索引库被删除了,所以查询不到了
2.1.5 总结
索引库操作有哪些?
-
创建索引库:PUT /索引库名
-
查询索引库:GET /索引库名
-
删除索引库:DELETE /索引库名
-
修改索引库,添加字段:PUT /索引库名/_mapping
可以看到,对索引库的操作基本遵循的Restful的风格,因此API接口非常统一,方便记忆。
三、文档操作
有了索引库,接下来就可以向索引库中添加数据了。
Elasticsearch中的数据其实就是JSON风格的文档。操作文档自然保护增
、删
、改
、查
等几种常见操作,我们分别来学习。
3.1 新增文档
1)语法
POST /索引库名/_doc/文档id
{
"字段1": "值1",
"字段2": "值2",
"字段3": {
"子属性1": "值3",
"子属性2": "值4"
},
}
2)示例
文档id需要自己指定,将来ES会根据文档id创建索引。如果不指定id的化,会随机生成id,这样将来再去操作文档的时候会很不方便。
POST /user/_doc/1
{
"info": "我是一名程序员",
"email": "zhangsan@123.com",
"age":12,
"sex":"男",
"name": {
"firstName": "张三",
"lastName": "张三"
}
}
3)实战演练
响应结果
3.2 查询文档
根据rest风格,新增是post,查询应该是get,不过查询一般都需要条件,这里我们把文档id带上。
1)语法
GET /{索引库名称}/_doc/{id}
2)示例
GET /user/_doc/1
3)实战演练
3.3 修改文档
3.3.1 全量修改
全量修改是覆盖原来的文档,其本质是两步操作:
-
根据指定的id删除文档
-
新增一个相同id的文档
注意:如果根据id删除时,id不存在,第二步的新增也会执行,也就从修改变成了新增操作了。可以理解为id存在则修改,不存在则创建。
1)语法
PUT /{索引库名}/_doc/文档id
{
"字段1": "值1",
"字段2": "值2",
// ... 略
}
2)示例
将 “我是一名程序员” 修改为 “我是一名JAVA程序员”
PUT /user/_doc/1
{
"info": "我是一名JAVA程序员",
"email": "zhangsan@123.com",
"age":12,
"sex":"男",
"name": {
"firstName": "张三",
"lastName": "张三"
}
}
3)实战演练
因为已经存在id为1的文档数据,执行的是修改操作,得到的反馈则是update
将id为1的记录删除,再执行, 由于id
为1
的文档已经被删除,所以第一次执行时,得到的反馈是created
3.3.2 局部修改
局部修改是只修改指定id匹配的文档中的部分字段。
1)语法
POST /{索引库名}/_update/文档id
{
"doc": {
"字段名": "新的值",
}
}
2)示例
将年龄改为18,性别改为女
POST /user/_update/1
{
"doc": {
"age": 18,
"sex": "女"
}
}
3)实战演练
查看结果
3.4 删除文档
1)语法
删除使用DELETE请求,同样,需要根据id进行删除:
DELETE /{索引库名}/_doc/id值
2)示例
DELETE /user/_doc/1
3) 实战演练
删除id为1的文档
再次查询id为1的文档,可以发现查询不到了
3.5 批量处理
Elasticsearch中允许通过一次请求中携带多次文档操作,也就是批量处理
1)语法
# 批量新增操作
POST _bulk
{ "index" : { "_index" : "test", "_id" : "1" } }
{ "field1" : "value1","field2" : "value2" }
{ "index" : { "_index" : "test", "_id" : "2" } }
{ "field1" : "value1","field2" : "value2" }
# 批量删除操作
POST _bulk
{ "delete" : { "_index" : "test", "_id" : "1" } }
{ "delete" : { "_index" : "test", "_id" : "2" } }
# 批量修改操作
{ "update" : {"_id" : "1", "_index" : "test"} }
{ "doc" : {"field1" : "value1"} }
{ "update" : {"_id" : "2", "_index" : "test"} }
{ "doc" : {"field2" : "value2"} }
其中:
index
代表新增操作
_index
:指定索引库名
_id
指定要操作的文档id
{ "field1" : "value1" }
:则是要新增的文档内容
delete
代表删除操作
_index
:指定索引库名
_id
指定要操作的文档id
update
代表更新操作
_index
:指定索引库名
_id
指定要操作的文档id
{ "doc" : {"field2" : "value2"} }
:要更新的文档字段
2)示例
注意:这里携带json参数不能换行
批量新增
POST /_bulk
{"index": {"_index":"user", "_id": "3"}}
{"info": "程序员C++讲师", "email": "ww@itcast.cn", "name":{"firstName": "五", "lastName":"王"}}
{"index": {"_index":"user", "_id": "4"}}
{"info": "程序员前端讲师", "email": "zhaoliu@itcast.cn", "name":{"firstName": "六", "lastName":"赵"}}
批量删除
POST /_bulk
{"delete":{"_index":"user", "_id": "3"}}
{"delete":{"_index":"user", "_id": "4"}}
3)实战演练
批量新增
查询结果
批量删除
这时候再去查询,查不到了
更新的操作大家可以自己尝试一下
3.6 总结
文档操作有哪些?
-
创建文档:
POST /{索引库名}/_doc/文档id { json文档 }
-
查询文档:
GET /{索引库名}/_doc/文档id
-
删除文档:
DELETE /{索引库名}/_doc/文档id
-
修改文档:
-
全量修改:
PUT /{索引库名}/_doc/文档id { json文档 }
-
局部修改:
POST /{索引库名}/_update/文档id { "doc": {字段}}
-