首页 > 其他分享 >Elastic学习之旅(4)ES文档CRUD操作

Elastic学习之旅(4)ES文档CRUD操作

时间:2024-02-25 19:56:12浏览次数:27  
标签:index Elastic doc CRUD 文档 type id ES

大家好,我是Edison。

上一篇:ES必备基础概念一览

ES文档CRUD介绍

和MongoDB一样,文档的CRUD是我们学习ES的必备操作,下图展示了ES文档的CRUD概要:

从上图可以知道,ES文档除了CRUD外,还多了一个Index操作,它的功能Create类似,但又有点不同:

  • Create - 如果ID存在,则会失败;否则新增成功;

  • Index - 如果ID存在,会先删除现有文档再创建新的,版本号会增加;否则,直接新增成功;

因此,我们可以说Index的功能或许可以叫 AddOrReplace。

Create文档

Create文档支持生成文档ID 和 指定文档ID 两种方式:

自动生成ID

通过调用 post {index}/_doc,系统会自动生成文档ID。

由上图可知,系统自动生成了一个ID。

指定ID

通过调用 put {index}/_create/1,系统会指定新生成文档ID为1。但如果指定ID已经存在,操作则失败。

由上图可知,我们传了一个指定ID=1。但是,如果我们再次执行这条语句会如何?

再次执行会报错,因为ES检测到这个数据版本已经存在了。

Get文档

通过get {index}/_doc/{id}即可快速查询一个文档数据,如果没有找到,则返回HTTP 404。

在返回的文档中,文档的真正内容在_source字段里面。

在返回的文档中,还包含了文档元信息:

  • _index / _type 

  • 版本信息,同一个ID的文档,即使被删除,version号也会不断增加 

  • _source中默认包含了文档的所有原始信息

Index文档

刚刚提到,Index 和 Create 不一样的地方在于:

  • 如果文档不存在,就索引新的文档。

  • 如果文档已存在,旧文档会先被删除,新文档会被索引,同时版本号+1。

因此,Index操作更像是我们所说的“AddOrReplace”。

通过put {index}/_doc/{id}即可完成Index操作,这里我们以刚刚get的示例为基础,修改id=1的user的username,由于id=1记录已存在,会先删除旧文档,再索引新文档:

从上图可以看到,当Index操作完成后,version号从1变为了2。

这时如果我们再查询一个id=1的文档,会发现已被新文档覆盖了,只有一个user字段了。

Update文档

Update方法就是真正的数据更新,它不会删除原来的文档。

通过post {index}/_update/{id}即可实现Update操作。

这时我们再次get一下,得到的结果:

可以看到,新增的数据已经加入了文档内容中,并且version又增加了一位。

Delete文档

可以通过 delete {index}/_doc/{id}来完成文档的删除操作。

可以看到,返回的结果状态显示为deleted,则表示删除成功。

这时如果再次查询这个文档,就会显示找不到了:

批量操作API(Bulk API)

ES提供了一个Bulk API,支持在一次API调用中,对不同的索引进行不同类型(如Index、Create、Update、Delete)的操作,可以有效减少网络连接所产生的开销。

POST _bulk
{ "index": { "_index":"test", "_id":"1" } }
{ "filed1": "value1" }
{ "delete": { "_index":"test", "_id":"2" } }
{ "create": { "_index":"test2", "_id":"3"  } }
{ "filed1": "value3" }
{ "update": { "_index":"test", "_id":"1" } }
{ "doc": { "field2":"value2" } }

其返回结果包含了每一条操作执行的结果。

{
  "took" : 854,
  "errors" : false,
  "items" : [
    {
      "index" : {
        "_index" : "test",
        "_type" : "_doc",
        "_id" : "1",
        "_version" : 1,
        "result" : "created",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 0,
        "_primary_term" : 1,
        "status" : 201
      }
    },
    {
      "delete" : {
        "_index" : "test",
        "_type" : "_doc",
        "_id" : "2",
        "_version" : 1,
        "result" : "not_found",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 1,
        "_primary_term" : 1,
        "status" : 404
      }
    },
    {
      "create" : {
        "_index" : "test2",
        "_type" : "_doc",
        "_id" : "3",
        "_version" : 1,
        "result" : "created",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 0,
        "_primary_term" : 1,
        "status" : 201
      }
    },
    {
      "update" : {
        "_index" : "test",
        "_type" : "_doc",
        "_id" : "1",
        "_version" : 2,
        "result" : "updated",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 2,
        "_primary_term" : 1,
        "status" : 200
      }
    }
  ]
}

需要注意的是:操作中单条操作失败,并不影响其他操作。此外,单次批量操作,数据量不宜过大,以免引发性能问题。

批量读取(mget)

和批量操作类似,ES提供了一个mget实现批量读取,可以减少网络连接产生的开销,提高读取的性能。

通过 get /_mget即可完成:

GET /_mget
{
  "docs":[
    {
      "_index":"users",
      "_id":1
    },
    {
      "_index":"users",
      "_id":2
    }
  ]
}

返回结果包含了多个数据:

{
  "docs" : [
    {
      "_index" : "users",
      "_type" : "_doc",
      "_id" : "1",
      "_version" : 1,
      "_seq_no" : 5,
      "_primary_term" : 1,
      "found" : true,
      "_source" : {
        "user" : "Andy",
        "postDate" : "2024-01-20T15:00:00",
        "message" : "Trying to use ElasticSearch"
      }
    },
    {
      "_index" : "users",
      "_type" : "_doc",
      "_id" : "2",
      "_version" : 1,
      "_seq_no" : 6,
      "_primary_term" : 1,
      "found" : true,
      "_source" : {
        "user" : "Wings",
        "postDate" : "2024-01-20T15:00:00",
        "message" : "Trying to use EFK"
      }
    }
  ]
}

批量查询(msearch)

和批量读取类似,ES提供了一个msearch实现批量查询,通过post {index}/_msearch即可完成:

POST users/_msearch
{}
{"query":{"match_all":{}},"size":3}
{"index":"movies"}
{"query":{"match_all":{}},"size":2}

例如上面这个批量查询,它从users中查询了3个数据 还从 movices中查询了2个数据出来:

{
  "took" : 7,
  "responses" : [
    {
      "took" : 7,
      "timed_out" : false,
      "_shards" : {
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 3,
          "relation" : "eq"
        },
        "max_score" : 1.0,
        "hits" : [
          {
            "_index" : "users",
            "_type" : "_doc",
            "_id" : "5-46K40BoVgALGyCI5vL",
            "_score" : 1.0,
            "_source" : {
              "user" : "Edison",
              "postDate" : "2024-01-20T14:00:00",
              "message" : "Trying to use Kibana"
            }
          },
          {
            "_index" : "users",
            "_type" : "_doc",
            "_id" : "1",
            "_score" : 1.0,
            "_source" : {
              "user" : "Andy",
              "postDate" : "2024-01-20T15:00:00",
              "message" : "Trying to use ElasticSearch"
            }
          },
          {
            "_index" : "users",
            "_type" : "_doc",
            "_id" : "2",
            "_score" : 1.0,
            "_source" : {
              "user" : "Wings",
              "postDate" : "2024-01-20T15:00:00",
              "message" : "Trying to use EFK"
            }
          }
        ]
      },
      "status" : 200
    },
    {
      "took" : 2,
      "timed_out" : false,
      "_shards" : {
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 9743,
          "relation" : "eq"
        },
        "max_score" : 1.0,
        "hits" : [
          {
            "_index" : "movies",
            "_type" : "_doc",
            "_id" : "3687",
            "_score" : 1.0,
            "_source" : {
              "year" : 0,
              "@version" : "1",
              "title" : "Light Years",
              "id" : "3687",
              "genre" : [
                "Adventure",
                "Animation",
                "Fantasy",
                "Sci-Fi"
              ]
            }
          },
          {
            "_index" : "movies",
            "_type" : "_doc",
            "_id" : "3688",
            "_score" : 1.0,
            "_source" : {
              "year" : 1982,
              "@version" : "1",
              "title" : "Porky's",
              "id" : "3688",
              "genre" : [
                "Comedy"
              ]
            }
          }
        ]
      },
      "status" : 200
    }
  ]
}

常见错误返回

ES的一些常见错误返回的表格,供我们学习参考。

小结

本篇,我们了解了ElasticSearch的一些必备基础概念,如索引、文档、集群、节点、分片与副本等。有了这些基本概念,我们可以知道ElasticSearch和关系型数据库的差别。

参考资料

极客时间,阮一鸣,《ElasticSearch核心技术与实战

 

作者:周旭龙

出处:https://edisonchou.cnblogs.com

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

标签:index,Elastic,doc,CRUD,文档,type,id,ES
From: https://www.cnblogs.com/edisonchou/p/-/edc_elastic_study_notes_chap04

相关文章

  • Go 100 mistakes - #69: Creating data races with append
        ......
  • Airtest结合Poco对控件实施精准截图
    1.前言最近在Q群内发现有个小伙伴提出了一个很有趣的脚本需求,想要实现“通过选择器获取到了控件,然后截图这个控件范围”,根据我们的Airtest的局部截图接口以及poco控件的属性查询接口是可以很快实现的~2.接口查找首先我们需要知道我们应该怎么实现用脚本去进行局部截图,我们可以通......
  • Airtest-Selenium实操小课:刷B站视频
    1.前言上一课我们讲到用Airtest-Selenium爬取网站上我们需要的信息数据,还没看的同学可以戳这里看看~那么今天的推文,我们就来说说看,怎么实现看b站、刷b站的日常操作,包括点击暂停,发弹幕,点赞,收藏等操作,仅供大家参考学习~2.需求分析和准备整体的需求大致可以分为以下步骤:打开chr......
  • 如何用Airtest实现在图片范围内随机点击
    1.前言前几天有个新手同学在Airtest官群里问了这样一个问题:我是新手,在图片范围内随机点击,用Airtest怎么实现?代码?那我们就以这个问题为例,浅浅聊一下,怎么把需求转化成我们的Airtest代码。2.了解Airtest首先新手同学对Airtest要有以下几点认知:①Airtest是一个图像识别框架......
  • Airtest:各平台的剪切板功能汇总
    1.前言一直以来,大家都还挺关注 Airtest是否有剪切板功能 的。从Airtest1.3.1版本起,我们新增了Android、iOS设备的剪切板功能,自此,3大平台的剪切板功能就齐全啦。正好趁这个机会,我们给各大平台的剪切板功能做个合集,方便同学们查阅使用~2.Android设备的剪切板功能Android设备的......
  • NanoFramework操作ESP32(一)_基础元器件篇(三十五)_ KY-040解码器
    一、元器件介绍    旋转编码器(增量式编码器)可通过旋转可以计数正方向和反方向转动过程中输出脉冲的次数,旋转计数不像电位计,这种转动计数是没有限制的。配合旋转编码器上的按键,可以复位到初始状态,即从0开始计数。旋转编码器目前被广泛的应用在数控机床、印刷设备、包装机械......
  • HUAWEI Programming Contest 2024(AtCoder Beginner Contest 342)
    HUAWEIProgrammingContest2024(AtCoderBeginnerContest342)A-Yay!代码:#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;usingpii=pair<ll,ll>;#definefifirst#definesesecondusingi128=__int128_t;usingpiii=p......
  • ssts-hospital-web-master项目实战记录十四:项目迁移-模块实现(file-system-object:FileS
    记录时间:2024-02-25一、准备工作【使用“文心一言”搜索使用ts实现类模块】在TypeScript中,类可以作为模块的一部分被导出,这样其他模块就可以导入并使用这些类。以下是如何使用TypeScript实现类模块的基本步骤:步骤1:定义类模块首先,在一个TypeScript文件中定义一个或多个......
  • Graph-Skeleton: ~1% Nodes are Sufficient to Represent Billion-Scale Graph
    目录概符号说明EmpiricalAnalysisSkeletonGraphNodeFetchingGraphCondensation代码CaoL.,DengH.,WangC.,ChenL.andYangY.Graph-skeleton:~1%nodesaresufficienttorepresentbillion-scalegraph.WWW,2024.概本文提出了一种图压缩的方法,这些方法基......
  • Codeforces Round 926 (Div. 2)
    A.升序排列再求和#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintN=1e5+10;#defineinf0x3f3f3f3fvoidsolve(){intn;cin>>n;vector<int>a(n+1);for(inti=1;i<=n;i++)cin>>a[i];sort(a.b......