内容目录

1.新建文档2.查询文档3.修改文档4.删除文档

1.新建文档

1). 语法1,手动指定document 的id:

PUT /index_name/type_name/id
{
    "Json format data"
}

举例:插入一条商品信息

PUT /goods/books/1
{
  "name":"effective java",
  "purchasePrice":7800,
  "salesPrice":12000,
  "currencyUnit":"cent",
  "desc":"Joshua Bloch",
  "onlineStock":999
}

运行结果:

{
  "_index" : "goods",
  "_type" : "books",
  "_id" : "1",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

可以看到,商品已经插入成功,ES自动为我们创建了index和type,若想禁止ES自动创建,我们可以修改config/elasticsearch.yml文件。

其中,输出中的 _index 元数据表明document 所在的index,index名称必须为小写字母,可以包含下划线、中划线,但只能以小写字母开头。在ES 6.6版本中,index的概念类似于mysql中的table,而非database。

同理,_type元数据表明document 所在的type,type是对document 的一个逻辑分类。

_id元数据表明document 的id,可以在创建document 时手动指定,也可以由ES自动生成,若由ES自动生成,我们应该用POST方法而非PUT方法,即下文的语法2。

_version表明当前document 的版本,_version元数据非常有效,从结果中我们可以看到,第一次创建document ,_version的值为1,其实以后我们对该document 进行修改或删除操作,_version的值都会加1,后续操作时,我们可以留意观察一下;另外,_version还被ES用于解决并发冲突的问题,当有并发请求时,ES内部实现了基于_version的乐观锁并发控制:当要修改document 数据时,带上数据的version版本号,只有version版本号相同时,ES才会更新数据,否则你需要先获取一下最新的数据,然后再带上最新的version去更新数据。

2). 语法2,document 的id由ES自动生成:

POST /index_name/type_name
{
    "Json format data"
}

举例:

POST /goods/books
{
  "name":"effective c++",
  "purchasePrice":4500,
  "salesPrice":5900,
  "currencyUnit":"cent",
  "desc":"Scott Meyers",
  "onlineStock":888
}

运行结果:

{
  "_index" : "goods",
  "_type" : "books",
  "_id" : "bEYCL2kB8EI9vT4zSMMW",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

可以看到ES为我们自动生成了id,长度20字符,是一种GUID,不会重复。

3). 语法3,利用 bulk API 的create 操作批量创建document :
bulk API 可以总结为:

{ action: { metadata }}\n
{ request body        }\n
{ action: { metadata }}\n
{ request body        }\n
......

批量创建document 则为:

POST /_bulk
{"create":{"_index":"index_name1","_type":"type_name1","_id":"id1"}}
{"field1":"field_data1","field2":"field_data2","field3":"field_data3"...}
{"create":{"_index":"index_name2","_type":"type_name2","_id":"id2"}}
{"field1":"field_data1","field2":"field_data2","field3":"field_data3"...}
...

若批量创建的document 在同一个index,则上述写法可以简写为

POST /index_name/_bulk
{"create":{"_type":"type_name1","_id":"id1"}}
{"field1":"field_data1","field2":"field_data2","field3":"field_data3"...}
{"create":{"_type":"type_name2","_id":"id2"}}
{"field1":"field_data1","field2":"field_data2","field3":"field_data3"...}
...

若批量创建的document 既在同一个index,又在同一个type中,则可以继续简写为

POST /index_name/type_name/_bulk
{"create":{"_id":"id1"}}
{"field1":"field_data1","field2":"field_data2","field3":"field_data3"}
{"create":{"_id":"id2"}}
{"field1":"field_data1","field2":"field_data2","field3":"field_data3"}
...

例如,批量创建ID为 8 和ID为 9 的商品,下面三种写法都可以:

POST /_bulk
{"create":{"_index":"goods","_type":"books","_id":"8"}}
{"name":"more Basic","salesPrice":1900,"onlineStock":134}
{"create":{"_index":"goods","_type":"books","_id":"9"}}
{"name":"more Pascal","salesPrice":1200,"onlineStock":234}

POST /goods/_bulk
{"create":{"_type":"books","_id":"8"}}
{"name":"more Basic","salesPrice":1900,"onlineStock":134}
{"create":{"_type":"books","_id":"9"}}
{"name":"more Pascal","salesPrice":1200,"onlineStock":234}

POST /goods/books/_bulk
{"create":{"_id":"8"}}
{"name":"more Basic","salesPrice":1900,"onlineStock":134}
{"create":{"_id":"9"}}
{"name":"more Pascal","salesPrice":1200,"onlineStock":234}

需要注意的是,利用bulk API 进行批量操作的时候,若其中一个操作失败,只会在操作结果中告诉我们,并不会影响到其他的操作,例如,现在 ES 中存在商品ID 为10的商品,不存在商品ID 为11的商品,此时运行

POST /goods/books/_bulk
{"create":{"_id":"10"}}
{"name":"more Basic","salesPrice":1900,"onlineStock":134}
{"create":{"_id":"11"}}
{"name":"more Pascal 11","salesPrice":1200,"onlineStock":234}

运行结果为

{
  "took" : 13,
  "errors" : true,
  "items" : [
    {
      "create" : {
        "_index" : "goods",
        "_type" : "books",
        "_id" : "10",
        "status" : 409,
        "error" : {
          "type" : "version_conflict_engine_exception",
          "reason" : "[books][10]: version conflict, document already exists (current version [1])",
          "index_uuid" : "UE-4WzIDTHqd7RpGX2QbMQ",
          "shard" : "1",
          "index" : "goods"
        }
      }
    },
    {
      "create" : {
        "_index" : "goods",
        "_type" : "books",
        "_id" : "11",
        "_version" : 1,
        "result" : "created",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 4,
        "_primary_term" : 3,
        "status" : 201
      }
    }
  ]
}

"errors" : true 表明此次 bulk 操作发生了error,相应位置的 item指出了具体的错误信息。

4). 语法4,利用 bulk API 的index 操作批量创建document
语法同bulk API 的create 操作,这里不再细说,直接举例子

例如,批量创建ID为 8 和ID为 9 的商品:

POST /goods/books/_bulk
{"index":{"_id":"8"}}
{"name":"more Basic","salesPrice":1900,"onlineStock":134}
{"index":{"_id":"9"}}
{"name":"more Pascal","salesPrice":1200,"onlineStock":234}

2.查询文档

1). 语法1,查询特定ID的document 信息:

GET /index_name/type_name/id

若只想查询商品的某个字段,可在id后拼接“?_source=field _name”,否则默认 _source 会返回所有的字段。

例如,查询ID为1的商品的名称:

GET /goods/books/1?_source=name

2). 语法2,批量查询:

GET /_mget
{
  "docs": [
      {
        "_index": "index_name1",
        "_type": "type_name1",
        "_id": "id1"
      },
      {
        "_index": "index_name2",
        "_type": "type_name2",
        "_id": "id2"
      }
    ......
    ]
}

若index_name 相同,则可以简写为

GET /index_name/_mget
{
  "docs": [
      {
        "_type": "type_name1",
        "_id": "id1"
      },
      {
        "_type": "type_name2",
        "_id": "id2"
      }
    ......
    ]
}

若index_name 和 type_name 均相同,则可以进一步简写为

GET /index_name/type_name/_mget
{
  "ids": ["id1", "id2"]
}

例如,查询ID为1 和 2的商品信息,下面三种写法都可以:

GET /_mget
{
  "docs": [
      {
        "_index": "goods",
        "_type": "books",
        "_id": "1"
      },
      {
        "_index": "goods",
        "_type": "books",
        "_id": "2"
      }
    ]
}

GET /goods/_mget
{
  "docs": [
      {
        "_type": "books",
        "_id": "1"
      },
      {
        "_type": "books",
        "_id": "2"
      }
    ]
}

GET /goods/books/_mget
{
  "ids": ["1", "2"]
}

3). 语法3,利用search API进行查询,后面会有单独一篇文章进行讲解。

3.修改文档

1). 语法1,PUT 方法,修改时所携带的field 会将document 已有的field 全部替换掉,即document 会进行全量替换,语法同创建文档:

PUT /index_name/type_name/id
{
    "Json format data"
}

举例:
先新增一条商品信息:

PUT /goods/books/1
{
  "name":"effective java",
  "purchasePrice":7800,
  "salesPrice":12000,
  "currencyUnit":"cent",
  "desc":"Joshua Bloch",
  "onlineStock":999
}

然后修改商品:

PUT /goods/books/1
{
  "name":"More Effective Java",
  "salesPrice":13000,
  "currencyUnit":"cent"
}

运行结果:

{
  "_index" : "goods",
  "_type" : "books",
  "_id" : "1",
  "_version" : 2,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 1,
  "_primary_term" : 1
}

从结果中可以看到version版本号更新为2,执行的操作是updated。此时执行查询操作,你会发现此document 仅剩下修改后的3个field 了。

其实document 是不可变的,这种方式修改 document 时,会对 document 建立一个新的索引,然后在新的索引中赋值所有的内容,老的document 会被标记为deleted,等待后续 ES 对其进行真正的物理删除。

既然全量替换的语法和创建文档的语法是相同的,那么如果我此刻就是想创建文档,而非全量替换文档,那我应该怎么做呢?别慌,问题不大,ES 提供了这个功能。

PUT /index_name/type_name/id?op_type=create
{
    "Json format data"
}

或者

PUT /index_name/type_name/id/_create
{
    "Json format data"
}

即可实现强制创建文档的功能。

2). 语法2,修改时携带哪个field,仅替换文档中相同的field

POST /index_name/type_name/id/_update
{
    "doc": {
        "Json format data"
    }
}

举例:
先新增一条商品信息:

PUT /goods/books/2
{
  "name":"effective python",
  "purchasePrice":5000,
  "salesPrice":6000,
  "currencyUnit":"cent",
  "desc":"Brett Slatkin",
  "onlineStock":666
}

然后修改商品:

POST /goods/books/2/_update
{
  "doc": {
    "name":"more effective python3",
    "salesPrice":8000,
    "desc":"handsome Brett Slatkin"
  }
}

运行结果:

{
  "_index" : "goods",
  "_type" : "books",
  "_id" : "2",
  "_version" : 2,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 1,
  "_primary_term" : 1
}

从结果中可以看到version版本号更新为2,执行的操作也是updated。此时执行查询操作,你会发现此document中其他field 保持不变,只有POST方法中携带的那三个field 发生了改变。这是与语法1很大的一个区别。

其实POST 这种方式的部分替换其内部执行过程和语法1的全量替换很像,ES会创建一个新的document,使用旧document的信息,然后ES 会将POST传递过来的json 更新到新的document 中,不过仅更新key 匹配的json 串,然后ES 会将旧的document 标记为deleted,将更新后的新的document 存入ES 中,这些操作都发生在一个shard中。

3). 语法3,利用bulk API 的index 操作,index 操作既可以批量创建文档,也可以全量替换文档,这里不再举例。

4). 语法4,利用bulk API 的update 操作,效果同 POST 操作,仅修改携带的field 域
例如,修改商品ID为8 和 9的商品的商品名称和在线库存

POST /goods/books/_bulk
{"update":{"_id":"8"}}
{"doc":{"name":"more Basic update","salesPrice":2300}}
{"update":{"_id":"9"}}
{"doc":{"name":"more Pascal update","onlineStock":12}}

4.删除文档

1). 语法1

DELETE /index_name/type_name/id

当执行delete 操作的时候,ES 并不会立刻将document 进行物理删除,而是先将document 标记为deleted,待后续ES 中数据越来越多时才会对标记为deleted的document 进行物理删除。

有时你会发现先将document 进行delete操作,然后又新建该document 时,新建的document 其实是基于已删的document 信息的,新建document 的_version是基于已删document 的 _version然后又加了1。

举例:新建ID为5的商品:

PUT /goods/books/5
{
  "name": "test book"
}

结果:

{
  "_index" : "goods",
  "_type" : "books",
  "_id" : "5",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 1,
  "_primary_term" : 1
}

删除该商品:

DELETE /goods/books/5

结果:

{
  "_index" : "goods",
  "_type" : "books",
  "_id" : "5",
  "_version" : 2,
  "result" : "deleted",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 2,
  "_primary_term" : 1
}

可以看到delete操作的结果中,_version 为2,此时再新建该商品:

PUT /goods/books/5
{
  "name": "test book"
}

结果:

{
  "_index" : "goods",
  "_type" : "books",
  "_id" : "5",
  "_version" : 3,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 9,
  "_primary_term" : 1
}

可以看到新建document 的 _version为3,即验证了上述我们所说的情况。

2). 语法2,利用bulk API 的delete操作

{ action: { metadata }}\n

举例,删除商品ID为8和9的商品

POST /_bulk
{"delete":{"_index":"goods","_type":"books","_id":"8"}}
{"delete":{"_index":"goods","_type":"books","_id":"9"}}

POST /goods/_bulk
{"delete":{"_type":"books","_id":"8"}}
{"delete":{"_type":"books","_id":"9"}}

POST /goods/books/_bulk
{"delete":{"_id":"8"}}
{"delete":{"_id":"9"}}

当然bulk API的create、index、update、delete操作可以一起使用,同样任意一个操作失败是不会影响到其他操作的,只是会在返回日志中说明。

如果这篇文章对你有帮助或启发,欢迎关注和转发,你的关注和转发是对我最大的支持。
如果你有什么疑问想要免费vip服务,欢迎扫描下方二维码,关注即可获得1v1免费vip服务。

![](https://img2018.cnblogs.com/blog/1046121/201905/1046121-20190526115340560-435847651.jpg)

【原创】《从0开始学Elasticsearch》—document的单/批量crud的更多相关文章

  1. 【原创】《从0开始学Elasticsearch》—初识Elasticsearch

    目录 1. Elasticsearch 是什么2. Elasticsearch 中基本概念3. Elasticsearch 安装4. 访问 Elasticsearch 1. Elasticsearch ...

  2. 【原创】《从0开始学Elasticsearch》—集群健康和索引管理

    内容目录 1.搭建Kibana2.集群健康3.索引操作 1.搭建Kibana 正如<Kibana 用户手册>中所介绍,Kibana 是一款开源的数据分析和可视化平台,因此我们可以借助 Ki ...

  3. SpringBoot(2.0.4.RELEASE)+Elasticsearch(6.2.4)+Gradle简单整合

    记录一下SpringBoot(2.0.4.RELEASE)+Elasticsearch(6.2.4)+Gradle整合的一个小例子. 1.在Gradle内加入相关jar包的依赖: compile('o ...

  4. <-0基础学python.第一课->

    初衷:我电脑里面的歌曲很久没换了,我想听一下新的歌曲,把他们下载下来听,比如某个榜单的,但是一首一首的点击下载另存为真的很恶心 所以我想有没有办法通过程序的方式来实现,结果还真的有,而且网上已经有有人 ...

  5. 如何从 0 开始学 ruby on rails (漫步版)

    如何从 0 开始学 ruby on rails (漫步版) ruby 是一门编程语言,ruby on rails 是 ruby 的一个 web 框架,简称 rails. 有很多人对  rails 感兴 ...

  6. 如何从 0 开始学 Ruby on Rails

    如何从 0 开始学 Ruby on Rails (漫步版)Ruby 是一门编程语言,Ruby on Rails 是 Ruby 的一个 web 框架,简称 Rails. 有很多人对 Rails 感兴趣, ...

  7. ELK6.0部署:Elasticsearch+Logstash+Kibana搭建分布式日志平台

    一.前言 1.ELK简介 ELK是Elasticsearch+Logstash+Kibana的简称 ElasticSearch是一个基于Lucene的分布式全文搜索引擎,提供 RESTful API进 ...

  8. ES 31 - 从0开始搭建Elasticsearch生产集群

    目录 1 配置环境 1.1 服务器IP映射 1.2 配置各节点的ssh免密通信 1.3 安装JDK并配置环境变量 2 部署单节点服务 3 部署集群服务 4 启动集群中的所有节点 4.2 启动各个节点中 ...

  9. 从0系统学Android-2.5更多隐式Intent用法

    本系列文章,参考<第一行代码>,作为个人笔记 更多内容:更多精品文章分类 从0系统学Android-2.5更多隐式Intent用法 上一节中我们学习了通过隐式 Intent 来启动 Act ...

随机推荐

  1. 2.6.2 用NPOI操作EXCEL--设置密码才可以修改单元格内容

    2.6.2 用NPOI操作EXCEL--设置密码       有时,我们可能需要某些单元格只读,如在做模板时,模板中的数据是不能随意让别人改的.在Excel中,可以通过“审阅->保护工作表”来完 ...

  2. OpenStack源码系列---起始篇

    近一年来我负责公司云点的自动化部署工作,包括公司自有云平台方案.XenServer.vSphere.Ovirt和OpenStack的自动化安装部署,目前已经到了OpenStack这一部分.自动化部署首 ...

  3. 关于yum的一些基本的东西

    1 sqlite数据库的使用 第一,某个centos版本的包相关的信息都放在一个服务器端的sqlite数据库文件中,yum会下载到本地,进行包安装的时候用. 第二,安装的历史记录放在sqlite数据库 ...

  4. nodejs的request模块

    request模块让http请求变的更加简单.(作为客户端,去请求.抓取另一个网站的信息) request的GitHub主页: https://github.com/request/request 最 ...

  5. mysql 数据库导入错误:40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET

    /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;/*!40101 SET @OLD_CHARACTER_SET_RES ...

  6. vue2-editor富文本基础使用方法

    vue2-editor的入门使用准备工作: 使用 npm install vue2-editor --save 安装到项目中去: 使用 在需要的单文件内引入 import { VueEditor } ...

  7. c语言基本函数

    1. 用宏定义写出swap(x,y) #define swap(x, y) x = x + y; y = x - y; x = x - y; 2.数组a[N],存放了1至N-1个数,其中某个数重复一次 ...

  8. bootstrap中的less

    一.如何加入变量 引入你的 .less 样式文件的时候要设置 rel 属性值为 “stylesheet/less”: 参考网站:http://www.bootcss.com/p/lesscss/  1 ...

  9. 皮尔逊相关系数的java实现

    相关系数的值介于–1与+1之间,即–1≤r≤+1.其性质如下:当r>0时,表示两变量正相关,r<0时,两变量为负相关.当|r|=1时,表示两变量为完全线性相关,即为函数关系.当r=0时,表 ...

  10. android.annotation.SuppressLint

    Lint是一个静态检查器,它围绕Android项目的正确性.安全性.性能.可用性以及可访问性进行分析.它检查的对象包括XML资源.位图.ProGuard配置文件.源文件甚至编译后的字节码. Lint包 ...