经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Elasticsearch » 查看文章
ES 16 - 对Elasticsearch中的索引数据进行增删改查 (CRUD)
来源:cnblogs  作者:马瘦风  时间:2019/4/15 8:55:57  对本文有异议

说在前面: 本文的所有演示, 都是基于Elasticsearch 6.6.10进行的, 不同的版本可能存在API发生修改、不支持的情况, 还请注意.

1 创建document

1.1 创建时手动指定id

(1) 适用情景:

从其他系统中导入数据到ES时, 会采取这种方式: 使用原有系统中数据已有的唯一标识, 作为ES中document的id.

而如果数据一生产出来就存储到了ES中, 一般是不适合手动指定id的.

(2) 使用语法:

  1. put index/type/id

(3) 使用示例:

  1. PUT employee/developer/1
  2. {
  3. "name": "shoufeng",
  4. "e_id": 5220
  5. }

(4) 添加成功后的响应信息:

  1. {
  2. "_index" : "employee",
  3. "_type" : "developer",
  4. "_id" : "1", // 指定了id, 控制底层的_id元字段
  5. "_version" : 1, // 当前版本号, 基于此字段进行并发控制
  6. "result" : "created",
  7. "_shards" : {
  8. "total" : 2, // 参与创建的分片数, 包括Primary和Replica
  9. "successful" : 1, // 成功创建索引的分片数量
  10. "failed" : 0 // 创建索引失败的分片数量
  11. },
  12. "_seq_no" : 0,
  13. "_primary_term" : 1
  14. }

1.2 创建时自动生成id

(1) 使用情景:

ES作为数据存储服务器, 应用程序中的数据直接对接到ES中, 这种场景适合自动生成id.

在多节点并发生成大量数据的场景下, 自动生成id更具安全性.

(2) 使用语法:

  1. POST index/type

(3) 使用示例:

  1. POST employee/developer
  2. {
  3. "name": "shoufeng",
  4. "sex": "male",
  5. "age": 20
  6. }

(4) 添加成功后的响应结果:

  1. {
  2. "_index" : "employee",
  3. "_type" : "developer",
  4. "_id" : "vMxcFWoBfKUnm9s_Uxen", // 没有指定id, 就会自动生成id, 长度为20个字符
  5. "_version" : 1,
  6. "result" : "created",
  7. "_shards" : {
  8. "total" : 2,
  9. "successful" : 1,
  10. "failed" : 0
  11. },
  12. "_seq_no" : 0,
  13. "_primary_term" : 1
  14. }

官方文档中指出:

Elasticsearch自动生成的id, 长度为20个字符, 是URL安全的, 它是Base64编码的GUID字符串, 多节点(分布式系统)并行生成id时不会发生冲突.

2 查看document

2.1 根据id查询文档

查询时可以不指定type, 即下述的developer, 而用_all代替.

  1. // 查询语法:
  2. GET employee/developer/1
  3. // 结果如下:
  4. {
  5. "_index" : "employee",
  6. "_type" : "developer",
  7. "_id" : "1",
  8. "_version" : 1,
  9. "_seq_no" : 0,
  10. "_primary_term" : 1,
  11. "found" : true,
  12. "_source" : { // 文档的元数据
  13. "name" : "shoufeng",
  14. "e_id" : 5220
  15. }
  16. }

2.2 通过_source字段控制查询结果

(1) 只获取指定id的文档的_source内容:

  1. GET employee/developer/1/_source
  2. // 结果是:
  3. {
  4. "name" : "shoufeng",
  5. "e_id" : 5220
  6. }

(2) 禁用指定id的文档的_source字段:

  1. GET employee/developer/1?_source=false
  2. // 结果是:
  3. {
  4. "_index" : "employee",
  5. "_type" : "developer",
  6. "_id" : "1",
  7. "_version" : 1,
  8. "_seq_no" : 0,
  9. "_primary_term" : 1,
  10. "found" : true
  11. }

(3) 过滤_source中的某些field:

  1. // _source_includes和_source_excludes可以匹配通配符*
  2. GET employee/developer/1?_source_includes=name,age&_source_excludes=sex
  3. GET employee/developer/_search?_source_includes=name,age&_source_excludes=sex

(4) 通过stored_fields API过滤文档中已存储的字段:

在Elasticsearch 6.0之后, 不再支持fields, 需要使用stored_fieldsAPI替换.

  1. GET employee/developer/1?stored_fields=name,age // 指定id
  2. GET employee/developer/_search?stored_fields=name,age // 不指定id, 将查询所有文档

其他查询操作, 将在后续的文章中专门记录.

3 修改document

3.1 全量替换document

全量替换是基于指定文档id的修改:

  1. // 语法与创建语法相同:
  2. PUT employee/developer/1
  3. {
  4. "name": "shoufeng001", // 修改姓名
  5. "age": 20, // 添加年龄
  6. "sex": "male", // 添加性别
  7. "e_id": 5220
  8. }

操作过程说明:

① 如果指定的document id不存在, 就是创建操作;
② 如果指定的document id已经存在, 就是全量替换操作 —— 替换旧文档的JSON串内容;
Lucene中倒排索引一旦被创建就是不可变的, 要修改文档内容, 可以采取全量替换的方式 —— 对文档重新建立索引, 替换旧文档的所有内容;
④ ES会将旧文档标记为deleted, 然后根据我们提交的请求创建一个新文档, 当标记为deleted的文档数达到一定量时, ES会在自动删除这些旧文档.

3.2 强制创建document

(1) 存在这样的场景:

我们不知道索引中是否已经存在某个文档 —— 可能有其他用户在并发添加文档;
为了防止创建操作被执行为全量替换操作, 从而导致数据的丢失, 我们可以使用强制创建的方式, 来避免这种失误.

(2) 强制创建示例:

  1. PUT employee/developer/1?op_type=create
  2. {
  3. "name": "shoufeng",
  4. "age": 20
  5. }
  6. // 或者使用:
  7. PUT employee/developer/1/_create
  8. {
  9. "name": "shoufeng",
  10. "age": 20
  11. }
  12. // 响应结果中出现冲突:
  13. {
  14. "error": {
  15. "root_cause": [
  16. { // 由于文档已经存在, 发生版本冲突, 导致创建失败
  17. "type": "version_conflict_engine_exception",
  18. "reason": "[developer][1]: version conflict, document already exists (current version [2])",
  19. "index_uuid": "OYu6J2x_S2S5v-R74aq6NQ",
  20. "shard": "3",
  21. "index": "employee"
  22. }
  23. ],
  24. "type": "version_conflict_engine_exception",
  25. "reason": "[developer][1]: version conflict, document already exists (current version [2])",
  26. "index_uuid": "OYu6J2x_S2S5v-R74aq6NQ",
  27. "shard": "3",
  28. "index": "employee"
  29. },
  30. "status": 409
  31. }

出现冲突的原因:

Elasticsearch通过乐观锁控制每个文档的_version信息, 强制创建语法会对当前操作的文档的_version信息进行初始化;

② 添加索引时, 发现已经存在对应id的文档, 而且其版本号与正在强制创建的文档的版本信息不匹配, 所以报错.

出现冲突后, 我们就能知道索引中已存在该文档了, 就可以根据自己的应用需求, 采取更改id后重新添加, 或者更改已有的文档等操作.

4 删除document

(1) 删除语法:

  1. DELETE index/type/id

(2) 删除示例:

  1. DELETE employee/developer/1
  2. // 再次查看id为1的文档, 发现"found": false

(3) Elasticsearch删除文档采取的是懒删除机制:

不会立即物理删除, 而是将其标记为deleted, 当被删除的文档数量达到一定级别后, ES会在后台自动删除这些文档.

版权声明

作者: 马瘦风

出处: 博客园 马瘦风的博客

您的支持是对博主的极大鼓励, 感谢您的阅读.

本文版权归博主所有, 欢迎转载, 但请保留此段声明, 并在文章页面明显位置给出原文链接, 否则博主保留追究相关人员法律责任的权利.

原文链接:http://www.cnblogs.com/shoufeng/p/10701141.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号