Elasticsearch CRUD

有了对ES的基本概念后,下面要做的就是了解如何与ES进行交流,ES非常贴心的提供了一套REST API让大家与他进行交流.这些API能做的事情包括以下几点

  • 检查你的集群,节点以及索引的状态信息
  • 管理你的集群,节点以及索引等的数据
  • 执行高级的搜索操作等
    总之有了这套REST API你几乎可以让ES干它所能干的所有事.

    状态查询API

    可以使用_cat API去查询集群节点索引等的状态.

查询集群健康状态

  1. clur localhost:9200/_cat/health?v查看集群状态,返回结果里有一个status的状态,它有三个值green,yellow,red
  • green表示一切OK,可以提供搜索服务

  • yellow表示所有的索引及其他状态都正常,但是副本数据不完整,有些分片没有副本数据,但是可以提供正常的搜索服务

  • red 表示部分数据丢失,能提供部分搜索服务

如果你是在本机上跑一个单节点的集群,那么status会是yellow的是因为,如果是单个节点,ES创建索引时并不会真的去分配副本,因为将副本和分片放在同一个节点里是无意义的,所以此处会返回yellow给出警告,如果当有新的Node加入,并且副本被分配到了新的节点里,这个索引的status就会变成green

  1. curl localhost:9200/_cat/nodes?v查看节点状态
  2. curl localhost:9200/_cat/indices?v查看索引状态`

索引和文档CRUD

目标数据

lang: json
1
2
3
4
5
6
7
{
"id": "1",
"title": "New version of Elasticsearch released!",
"content": "Version 1.0 released today!",
"priority": 10,
"tags": ["announce", "elasticsearch", "release"]
}

可以看到JSON文档包含一组字段, "id": "1"一个字段,"content": "Version 1.0 released today!"另一个字段,他们都有各自的类型ES会识别出这些类型.

建立索引

ES为我们提供了一个强大的REST API用来操作ES服务,使用下面的命令来为上面的数据建立索引

手动指定文档唯一标识符

1
2
3
4
5
6
7
curl -XPOST http://localhost:9200/blog/article/1 -d '{
"id": "1",
"title": "New version of Elasticsearch released!",
"content": "Version 1.0 released today!",
"priority": 10,
"tags": ["announce", "elasticsearch", "release"]
}'

blog article 1 分别是我们建立的索引名称 文档名称 和唯一标识符

执行成功后的返回结果:

lang: json
1
2
3
4
5
6
7
8
9
10
11
12
13
{
"_index":"blog",
"_type":"article",
"_id":"1",
"_version":1,
"_shards":
{
"total":2,
"successful":1,
"failed":0
},
"created":true
}

  • _index: 表示建立索引的名称blog(database name)
  • _type: 表示索引的类型 article(table name)
  • _Id: 表示文档的唯一标识符 1 (可以理解为表的primary key)
  • _version: 表示版本信息,该值由ES维护,每次更新索引的时候_version会自动递增
  • _shards: 表示其分片信息

如果重复创建Id相同的Document时,只会由ES去更新Document,相应的_version也会递增

自动生成文档的唯一标识符

只需要将put操作换成post即可,ES会自动为我们的Document生成唯一的标识符.

1
2
3
4
5
6
7
curl -XPOST http://localhost:9200/blog/article -d '{
"id": "1",
"title": "New version of Elasticsearch released!",
"content": "Version 1.0 released today!",
"priority": 10,
"tags": ["announce", "elasticsearch", "release"]
}'

返回结果:

lang: json
1
2
3
4
5
6
7
8
9
10
11
12
13
{
"_index":"blog",
"_type":"article",
"_id":"AVJe9pBhG_DRWvBx76jq",
"_version":1,
"_shards":
{
"total":2,
"successful":1,
"failed":0
},
"created":true
}

  • 上面AVJe9pBhG_DRWvBx76jq是由ES自动生成的文档的唯一标识

创建空的索引

除了创建包含有文档和类型的索引之外,还可以穿件一个空的索引,里面不包含任何Document和Type

1
curl -XPOST localhost:9200/empty_index

返回结果:

1
{"acknowledged":true}

  • 一般情况下我们不需要这么做,直接创建正常的索引就行了,如果索引里面没有数据,那么这个索引也是多余的.

更新文档

在更新文档的时候,ES并不是直接对已经经过索引的文档进行修改,而是删除旧的文档,并使用新的数据重新索引

  • 只更新title

    1
    2
    3
    curl -XPOST localhost:9200/blog/article/1/_update?pretty -d '{
    "doc": { "title": "New Title" }
    }'
  • 更新title, 并添加author字段.

    1
    2
    3
    curl -XPOST localhost:9200/blog/article/1/_update?pretty -d '{
    "doc": { "title": "New Title again !", "author": "ES" }
    }'

删除文档

删除之前创建的index: blog, type: article, id: 1 的文档

1
curl -XDELETE localhost:9200/blog/article/1

返回结果:

lang: json
1
2
3
4
5
6
7
8
9
10
11
12
{
"found":true,
"_index":"blog",
"_type":"article",
"_id":"1",
"_version":3,
"_shards":{
"total":2,
"successful":1,
"failed":0
}
}

删除索引

1
curl -XDELETE localhost:9200/blog/article/1

返回结果:

1
{"acknowledged":true}

与创建空索引成功的返回值一样,只返回这个?,是不是意味着ES并没有真正的删除索引内部的数据呢?而是对那些数据进行了标记,然后再以后创建新的索引的时候直接覆盖掉这些数据呢?这个需要进一步研究一下.

总结

以上ES的REST API 都是按照下面的协议来定义的:

1
curl -X<REST Verb> <Node>:<Port>/<Index>/<Type>/<ID>

参考

Elasticsearch Getting Started