一 . 添加文档
在上面一节,我们删除了user索引.
现在我们执行下面的命令:
PUT /user/_doc/1 { "username" : "trek", "age" : 27 }
可以得到下面的结果
{ "_index" : "user", "_type" : "_doc", "_id" : "1", "_version" : 1, "result" : "created", "_shards" : { "total" : 2, "successful" : 1, "failed" : 0 }, "_seq_no" : 0, "_primary_term" : 1 }
我们从result之中,可以得到,我们成功的添加了一个文档.
我们继续查询索引:
GET /user
可以得到如下的结果:
{ "user" : { "aliases" : { }, "mappings" : { "properties" : { "age" : { "type" : "long" }, "username" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } } } }, "settings" : { "index" : { "creation_date" : "1569423964719", "number_of_shards" : "1", "number_of_replicas" : "1", "uuid" : "_7BZkTRISAm7zzCo5B17ow", "version" : { "created" : "7030299" }, "provided_name" : "user" } } } }
我们发现,我们在添加记录的时候,同时也创建了索引.
这就是nosql数据库的特点,它总是没有什么特定的要求的.
二 .文档的id
在上面,我们添加一个文档,并且制定了文档的id是1.
如果我们不指定,es会帮助我们自动生成一个文档的id.
如下:
POST /user/_doc { "username":"tom", "age" : 33 }
得到的结果如下:
{ "_index" : "user", "_type" : "_doc", "_id" : "6pr4aG0BsjQtAa68ty9w", "_version" : 1, "result" : "created", "_shards" : { "total" : 2, "successful" : 1, "failed" : 0 }, "_seq_no" : 1, "_primary_term" : 1 }
我们发现es给我们创建了一个随机的id值.
另外,我们可以得到这样的一个结论.
put请求的本质实际上是更新,如上.
post的请求本质上才是新增.当我们不指定id的时候,es就会执行新增操作.
如果指定了id,es的处理逻辑就是更新.
但是es是不允许更新文档内容的,它处理的逻辑是先删除,然后再添加一个新的文档.
由于我们之前不存在id=1的文档,因此es知道我们的本意其实是新增.
在这里我们说的put和post的区别,在后面也是相同的.
如果不分析这些,我们很容易的就认为put是新增操作,和一般的restful风格不一致.
四 .全量更新
在更新内容的时候,我们需要指定id.
如下:
PUT /user/_doc/1 { "username":"tim" }
得到的结果如下:
{ "_index" : "user", "_type" : "_doc", "_id" : "1", "_version" : 2, "result" : "updated", "_shards" : { "total" : 2, "successful" : 1, "failed" : 0 }, "_seq_no" : 2, "_primary_term" : 1 }
我们需要注意的是version的内容现在变成了2,这是乐观所的机制,在这里我们不去详细的说.
我们再去查询id=1的文档内容.
GET /user/_doc/1
得到如下的内容,我们关注下_source的内容.
{ "_index" : "user", "_type" : "_doc", "_id" : "1", "_version" : 2, "_seq_no" : 2, "_primary_term" : 1, "found" : true, "_source" : { "username" : "tim" } }
令我们感到惊讶的是,我们原本想更新username的内容,但是es不仅帮助我们更新了该字段,而且删除了age字段.
原因呢?
和我们上面介绍的内容其实是一致的,es的文档没有更新的操作,只有先删除后新增的功能.
我们上述的命令,本质上是就是如此,因此,新增的文档根本没有age字段,该字段丢失了.
很多情况下,我们不想出现这样的效果.
四 .局部更新--partial update操作.
看如下的命令:
我们首先创建如下的文档:
PUT /user/_doc/3 { "username":"john", "age":33 }
使用下面的命令进行更新:
POST /user/_update/3 { "doc":{ "username":"john", "age":34 } }
我们使用的局部更新的操作,该操作会更新局部的内容.
五 .删除文档
DELETE /user/_doc/1
我们发送delete请求就可以正确的删除文档了.