ElasticSearch知识点记录

本文详细介绍了Elasticsearch(ES)的核心概念,包括倒排索引、Lucene的关系、ES的高可用性、分布式特性以及索引管理。内容涵盖了全文检索、短语搜索、聚合分析、分布式结构、shard与replica、数据容错机制、元数据(_index、_type、_id)以及数据写入和恢复原理。通过对Elasticsearch的工作原理和最佳实践的探讨,帮助读者深入理解ES的使用和优化。
摘要由CSDN通过智能技术生成

ElasticSearch

一 ElasticSearch

1.1 全文检索,倒排索引

倒排索引:给每一个数据都设定一个id,倒排索引看起来类似下图,是将每一个词条都拆开来,将所有的拆出来的词全部排列,建立倒排索引,搜索的时候也会将搜索词进行拆分,然后将拆分后的词放入倒排索引进行查询
倒排索引(Inverted Index)也叫反向索引,有反向索引必有正向索引。通俗地来讲,正向索引是通过key找value,反向索引则是通过value找key。
在这里插入图片描述
利用倒排索引进行全文索引,假设100万条数据,拆分出来的词语,假设有100万个词语,那么在倒排索引中,就有1000万行,优化搜索算法,有可能快速的查询到想要查询的词 。

1.2 Lucene

就是一个jar包,里面包含了封装好的各种建立倒排索引,以及进行搜索的代码,包括各种算法。一般就用Java开发时,引用Lucene jar,基于Lucene的api进行开发就可以了。我们就可以去将已有的数据建立索引,Lucene会在本地磁盘上面,给我们组织索引的数据结构。另外的话,我们也可以用Lucene提供的一些功能和api来针对磁盘上的索引数据,进行搜索。

1.3 什么是ElasticSearch

Lucene封装了搜索引擎的功能
ElasticSearch 底层会封装Lucene,elasticSearch是多个节点
es的特点和优点:
1.自动维护数据的冗余副本,保证数据不丢失,由于宕机
2.封装了Lucene,提升高级api,能快速开发复杂的功能
3.基于地理位置的搜索,搜索距离我当前一公里的烤肉店
4.自动维护数据的分布到多个节点的索引的建立,还有搜索请求分布到多个节点的执行

Elasticsearch 分布式,高可用,可伸缩,高性能

1.4 Elasticsearch的功能

1)分布式的搜索引擎和数据分析引擎
搜索:百度,网站的站内搜索,IT系统的检索
数据分析:电商网站,最近七天牙膏这种商品销量排名前十的商家有哪些

分布式,搜索,数据分析

2)全文检索,结构化检索,数据分析
全文检索:我想搜索商品名称包含牙膏的商品 like
结构化搜索:我想搜索商品分类为日化用品的商品有哪些 =
部分匹配,自动完成,搜索纠错,搜索推荐
数据分析:我想分析每一个商品分类下有多少个商品 group by

3)对海量数据进行近实时的处理
分布式:ES自动可以将海量数据分散到多台服务器上存储和检索
海量数据的处理:分布式以后,就可以采用大量的服务器和检索数据,自然而然就可以实现海量数据的处理了
近实时:在秒级别对数据进行搜索和分析
跟分布式/海量数据相反的:lucene,单机应用,只能在单台机器上使用,最多只能处理单台服务器的数据量

1.5 elasticsearch的适用场景

维基百科
国外新闻网站,类似搜狐新闻
Stack Overflow
GitHub
电商网站
日志数据分析,Logstash采集日志,es进行复杂的数据分析
商品价格监控网站,用户设定某商品的价格阈值的时候,发送通知消息给用户
BI系统,ES执行数据分析和挖掘,Kibana进行数据可视化

1.6 elasticsearch的特点

  1. 可以作为一个大型分布式集群(数百台服务器)技术,处理PB级数据
  2. Elasticsearch不是什么新技术,主要是将全文检索、数据分析以及分布式技术,合并成了独一无二的ES
  3. 对用户而言,是开箱即用的,非常简单,作为中小型的应用,直接3分支部署一下es,就可以作为生产环境的系统来使用,数据量不大,操作不是太复杂
  4. 数据库的功能面对很多领域是不够用的(事务,还有各种联机事务型操作);特殊的功能,比如,相关度排名,复杂数据分析,海量数据的近实时处理;Elasticsearch作为传统数据库的一个补充,提供了数据库所不能提供的很多功能

二 Elasticsearch的核心概念

2.1 Lucene和ElasticSearch的前世今生

Lucene:最先进、功能最强大的搜索库,直接基于Lucene开发,非常复杂,api复杂,需要深入理解原理
elasticsearch,基于Lucene,隐藏复杂性,提供简单易用的restful api接口、java api接口(还有其他语言的api接口)

  1. 分布式文档存储引擎
  2. 分布式的搜索引擎和分析引擎
  3. 分布式,支持PB级数据

开箱即用,优秀的默认参数,不需要任何额外设置,完全开源

2.2 elasticsearch的核心概念

Near Realtime(NRT):近实时,两个意思,从写入数据到数据可以被搜索到有一个延迟(大概1秒);基于es执行搜索和分析可以达到秒级
cluster:集群,包含多个节点,每个节点属于哪个集群是通过一个配置(集群名称,默认是elasticsearch)来决定的,对于中小型应用来说,刚开始一个集群就一个节点很正常
Node:节点,集群中的一个节点,节点也有一个名称(默认随机分配的),节点名称很重要(在执行运维管理操作的时候),默认节点会去加入一个名称为“elasticsearch”的集群,如果直接启动一堆节点,那么它们会自动组成一个elasticsearch集群,当然一个节点也可以组成一个elasticsearch集群
Document:文档,es中最小数据单元,一个document可以是一条客户数据,通常用JSON数据结构表示,每个Index下的type中,都可以存储多个document,一个document里面有多个field,每个field就是一个数据字段
Index:索引,包含一堆有相似的文档数据,比如可以有一个客户索引,商品分类索引,订单索引。
Type:类型,每个索引里都可以有一个或多个type,type是index中的一个逻辑数据分类,一个type下的document,都有相同的field。
shard:单台机器无法存储大量数据,es可以将一个索引中的数据切分为多个shard,分布在多台服务器上存储。有了shard就可以横向扩展,存储更多数据,让搜索和分析等操作分布到多台服务器上去执行,提升吞吐量和性能。每个shard都是一个lucene index。
replica:任何一个服务器随时可能故障或宕机,此时shard可能就会丢失,因此可以为每个shard创建多个replica副本。replica可以在shard故障时提供备用服务,保证数据不丢失,多个replica还可以提升搜索操作的吞吐量和性能。primary shard(建立索引时一次设置,不能修改,默认5个),replica shard(随时修改数量,默认1个),默认每个索引10个shard,5个primary shard,5个replica shard,最小的高可用配置,是2台服务器。

2.3 full-text search(全文检索)

get /ecommerce/product/_search
{
   
    "query": {
   
        "match": {
   
            "producer": "yagao producer"
        }
    }
}

producer 这个字段,会先被拆解,建立倒排索引
special 4
yago 4
producer 1,2,3,4
gaolujie 1
zhonghua 3
jiajieshi 2

2.4 phrase search (短语搜索)

match_phrase
跟全文检索相对应,相反,全文检索会将输入的搜索串拆解开来,去倒排索引里面去一一匹配,只要能匹配上任意一个拆解后的单词,就可以作为结果返回
phrase search 要求输入的搜索串,必须在指定的字段文本中,完全包含一模一样的,才可以算匹配,才能作为结果返回

2.5 elasticsearch 聚合分析

聚合分析的需求:先分组,再算每组的平均值,计算每个tag下的商品的平均价格

GET /ecommerce/product/_search
{
   
    "size": 0,
    "aggs" : {
   
        "group_by_tags" : {
   
            "terms" : {
    "field" : "tags" },
            "aggs" : {
   
                "avg_price" : {
   
                    "avg" : {
    "field" : "price" }
                }
            }
        }
    }
}

数据分析需求:计算每个tag下的商品的平均价格,并且按照平均价格降序排序

GET /ecommerce/product/_search
{
   
    "size": 0,
    "aggs" : {
   
        "all_tags" : {
   
            "terms" : {
    "field" : "tags", "order": {
    "avg_price": "desc" } },
            "aggs" : {
   
                "avg_price" : {
   
                    "avg" : {
    "field" : "price" }
                }
            }
        }
    }
}

数据分析需求:按照指定的价格范围区间进行分组,然后在每组内再按照tag进行分组,最后再计算每组的平均价格

GET /ecommerce/product/_search
{
   
  "size": 0,
  "aggs": {
   
    "group_by_price": {
   
      "range": {
   
        "field": "price",
        "ranges": [
          {
   
            "from": 0,
            "to": 20
          },
          {
   
            "from": 20,
            "to": 40
          },
          {
   
            "from": 40,
            "to": 50
          }
        ]
      },
      "aggs": {
   
        "group_by_tags": {
   
          "terms": {
   
            "field": "tags"
          },
          "aggs": {
   
            "average_price": {
   
              "avg": {
   
                "field": "price"
              }
            }
          }
        }
      }
    }
  }
}

2.6 ES的基础分布式结构

在这里插入图片描述
1.ElasticSearch对复杂分布式机制的透明隐藏特性
2.ElasticSearch的垂直扩容与水平扩容
3.增减或减少节点的数据rebalance
4.master节点
5.节点对等的分布式架构

2.7 primary&replica shard

1)index包含多个shard
2)每个shard都是一个最小工作单元,承载部分数据,Lucene实例,完整的建立索引和处理请求的能力
3)增减节点时,shard 会自动在nodes中负载均衡
4)primary shard和replica shard,每个document肯定只存在某一个primary shard以及其对应的replica shard中,不可能存在于多个primary shard
5)replica shard是primary shard的副本,负责容错,以及承担读请求负载
6)primary shard的数量在创建索引的时候就固定了,replica shard的数量可以随时修改
7)primary shard的默认数量是5,replica默认是1,默认有10个shard,5个primary shard,5个replica shard
8)primary shard不能和自己的replica shard放在同一个节点上,但是可以和其他primary shard的replica shard放在同一个节点上
在这里插入图片描述

2.8 ES横向扩容

图解横向扩容过程,如何超出扩容极限,以及如何提升容错性
1)primary&replica自动负载均衡,6个shard,3 primary,3 replica
2)每个node有更少的shard,IO/CPU/Memory资源给每个shard分配更多,每个shard性能更好
3)扩容的极限,6个shard(3 primary,3 replica),最多扩容到6台机器,每个shard可以占用单台服务器的所有资源,性能最好
4)超出扩容极限,动态修改replica数量,9个shard(3 primary,6 replica),扩容到9台机器,比3台机器时,拥有3倍的读吞吐量
5)3台机器下,9个shard(3 primary ,6 replica),资源更少,但是容错性更好,做多容纳2台机器宕机,6个shard只能容纳1台机器宕机
6)这里的这些知识点,你综合起来看,就是说,一方面告诉你扩容的原理,怎么扩容,怎么提升系统整体吞吐量:另一方面要考虑到系统的容错性,怎么保证提高容错性,让尽可能多的服务器宕机,保证数据不丢失
扩容过程分析
容错纠正

2.9 ES容错机制

ElasticSearch容错机制:master选举,replica容错,数据恢复
1)9 shard, 3 node
2)master node宕机,自动master选举,red
3)replica容错:新master将replica提升为primary shard,yellow
4)重启宕机node,master copy replica到该node,使用原有的shard并同步宕机后的修改,green
在这里插入图片描述

2.10 ES _index/_type/_id 元数据介绍

{
   
  "_index": "test_index",
  "_type": "test_type",
  "_id": "1",
  "_version": 1,
  "found": true,
  "_source": {
   																												
    "test_content": "test test"
  }
}

1、_index元数据
(1)代表一个document存放在哪个index中
(2)类似的数据放在一个索引,非类似的数据放不同索引:product index(包含了所有的商品),sales index(包含了所有的商品销售数据),inventory index(包含了所有库存相关的数据)。如果你把比如product,sales,human resource(employee),全都放在一个大的index里面,比如说company index,不合适的。
(3)index中包含了很多类似的document:类似是什么意思,其实指的就是说,这些document的fields很大一部分是相同的,你说你放了3个document,每个document的fields都完全不一样,这就不是类似了,就不太适合放到一个index里面去了。
(4)索引名称必须是小写的,不能用下划线开头,不能包含逗号:product,website,blog

2、_type元数据
(1)代表document属于index中的哪个类别(type)
(2)一个索引通常会划分为多个type,逻辑上对index中有些许不同的几类数据进行分类:因为一批相同的数据,可能有很多相同的fields,但是还是可能会有一些轻微的不同,可能会有少数fields是不一样的,举个例子,就比如说,商品,可能划分为电子商品,生鲜商品,日化商品,等等。
(3)type名称可以是大写或者小写,但是同时不能用下划线开头,不能包含逗号

3、_id元数据
(1)代表document的唯一标识,与index和type一起,可以唯一标识和定位一个document
(2)我们可以手动指定document的id(put /index/type/id),也可以不指定,由es自动为我们创建一个id

2.11 ES id生成的两种方式

一般来说,是从某些其他的系统中,导入一些数据到es时,会采取这种方式,就是使用系统中已有数据的唯一标识,作为es中document的id。举个例子,比如说,我们现在在开发一个电商网站,做搜索功能,或者是OA系统,做员工检索功能。这个时候,数据首先会在网站系统或者IT系统内部的数据库中,会先有一份,此时就肯定会有一个数据库的primary key(自增长,UUID,或者是业务编号)。如果将数据导入到es中,此时就比较适合采用数据在数据库中已有的primary key。

如果说,我们是在做一个系统,这个系统主要的数据存储就是es一种,也就是说,数据产生出来以后,可能就没有id,直接就放es一个存储,那么这个时候,可能就不太适合说手动指定document id的形式了,因为你也不知道id应该是什么,此时可以采取下面要讲解的让es自动生成id的方式。

1、手动指定document id

put /index/type/id
PUT /test_index/test_type/2
{
   
  "test_content": "my test"
}

2、自动生成document id

POST /index/type
POST /test_index/test_type
{
   
  "test_content": "my test"
}

{
   
  "_index": "test_index",
  "_type": "test_type",
  "_id": "AVp4RN0bhjxldOOnBxaE",
  "_version": 1,
  "result": "created",
  "_shards": {
   
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "created": true
}

自动生成的id,长度为20个字符,URL安全,base64编码,GUID,分布式系统并行生成时不可能会发生冲突

GUID算法不冲突解释:
GUID算法不冲突解释

2.12 _source元数据

1、_source元数据

put /test_index/test_type/1
{
   
  "test_field1": "test field1",
  "test_field2": "test field2"
}
get /test_index/test_type/1
result:
{
   
  "_index": "test_index",
  "_type": "test_type",
  "_id": "1",
  "_version": 2,
  "found": true,
  "_source": {
   
    "test_field1": "test field1",
    "test_field2": "test field2"
  }
}

_source元数据:就是说,我们在创建一个document的时候,使用的那个放在request body中的json串,默认情况下,在get的时候,会原封不动的给我们返回回来。

2、定制返回结果
定制返回的结果,指定_source中,返回哪些field

GET /test_index/test_type/1?_source=test_field1,test_field2
result:
{
   
  "_index": "test_index",
  "_type": "test_type",
  "_id": "1",
  "_version": 2,
  "found": true,
  "_source": {
   
    "test_field2": "test field2"
  }
}

2.13 document的全量替换、强制创建、删除

1、document的全量替换
(1)语法与创建文档是一样的,如果document id不存在,那么就是创建;如果document id已经存在,那么就是全量替换操作,替换document的json串内容
(2)document是不可变的,如果要修改document的内容,第一种方式就是全量替换,直接对document重新建立索引,替换里面所有的内容
(3)es会将老的document标记为deleted,然后新增我们给定的一个document,当我们创建越来越多的document的时候,es会在适当的时机在后台自动删除标记为deleted的document

2、document的强制创建
(1)创建文档与全量替换的语法是一样的,有时我们只是想新建文档,不想替换文档,如果强制进行创建呢?
(2)PUT /index/type/id?op_type=create,PUT /index/type/id/_create

3、document的删除
(1)DELETE /index/type/id
(2)不会理解物理删除,只会将其标记为deleted,当数据越来越多的时候,在后台自动删除

2.13 ES并发冲突

在这里插入图片描述

2.14 ES内部如何基于_version进行乐观锁并发控制

悲观锁与乐观锁两种并发控制方案
在这里插入图片描述
mysql 采用悲观锁技术
ES 采用乐观锁技术,乐观锁引入 version

悲观锁与乐观锁
1.悲观锁的优点是:方便,直接加锁,对应用程序来说,透明,不需要做额外的操作;缺点,并发能力很低,同一时间只能有一条线程操作数据
2.乐观锁的优点是:并发能力很高,不给数据加锁,大量线程并发操作;缺点,麻烦,每次更新的时候,都要先对比版本号,然后可能需要重新加载数据,再次修改,再写;这个过程可能要重复好几次。

_version
每一次创建一个document的时候,它的_version内部版本号就是1;以后,每次对这个document执行修改或者删除操作,都会对这个_version版本号自动加1;哪怕是删除,也会对这条数据的版本号加1

PUT /test_index/test_type/6
{
   
  "test_field": "test test"
}

{
   
  "_index": "test_index",
  "_type": "test_type",
  "_id": "6",
  "_version": 1,
  "result": "created",
  "_shards": {
   
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "created": true
}
{
   
  "found": true,
  "_index": "test_index",
  "_type": "test_type",
  "_id": "6",
  "_version": 4,
  "result": "deleted",
  "_shards": {
   
    "total": 2,
    "successful": 1,
    "failed": 0
  }
}

我们会发现,在删除一个document之后,可以从侧面证明,它不是立即物理删除的,因为它的一些版本号信息还是保留着的。先删除一条document,再重新创建这条document,其实会在delete version基础之上,再把version号加1。

es 中的数据的版本号,跟客户端中的数据的版本号是相同才能修改
基于最新的数据和版本号,去进行修改,修改后,带上最新的版本号,可能这个步骤会需要反复执行好几次,才能成功,特别是在多线程并发更新同一条数据很频繁的情况下

external version
es 提供了一个feature,就是说,你可以不用它提供的内部_version 版本号来进行并发控制,可以基于你自己维护的一个版本号来进行并发控制。举个例子,加入你的数据在mysql里也有一份,然后你的应用系统本身就维护了一个版本号,无论是自己生成的,程序控制的。这个时候,你进行乐观锁并发控制的时候,可能并不是想要的es 内部的_version 来进行控制,而是用你自己维护的那个version 来进行控制。
?version=1
?version=1&version_type=external

version_type=external,唯一的区别在于,_version,只有当你提供的version 与 es 中的_version一模一样的时候,才可以进行修改,只要不一样,就报错;当version_type=external的时候,只有当你提供的version比es中的_version大的时候,才能完成修改

es,_version=1,?version=1,才能更新成功
es,_version=1,?version>1&version_type=external,才能成功,比如说?version=2&version_type=external

2.15 partial update实现原理

1. 什么是 partial update?
PUT /index/type/id,创建文档&替换文档,就是一样的语法

一般对应到应用程序中,每次的执行流程基本是这样的:
(1)应用程序先发起一个get请求,获取到document,展示到前台界面,供用户查看和修改
(2)用户在前台界面修改数据,发送到后台
(3)后台代码,会将用户修改的数据在内存中进行执行,然后封装好修改后的全量数据
(4)然后发送PUT请求,到es中,进行全量替换
(5)es将老的document标记为deleted,然后重新创建一个新的document

partial update

post /index/type/id/_update 
{
   
   "doc": {
   
      "要修改的少数几个field即可,不需要全量的数据"
   }
}

看起来,好像就比较方便了,每次就传递少数几个发生修改的field即可,不需要将全量的document数据发送过去

PUT /test_index/test_type/10
{
   
  "test_field1": "test1",
  "test_field2": "test2"
}
POST /test_index/test_type/10/_update
{
   
  "doc": {
   
    "test_field2": "updated test2"
  }
}

partial update 相较于全量替换的优点
1.所有的查询、修改和写回操作,都发生在es中的一个shard 内部,避免了所有的网络数据传输的开销(减少2次网络请求),大大提升了性能(全量替换的查询、修改是发生在java或别的程序中的)
2.减少了查询和修改中的时间间隔,可以有效减少并发冲突的情况

groovy 脚本进行 partial update
es,有个内置脚本支持,可以基于groovy实现各种各样复杂操作
(1)内置脚本

POST /test_index/test_type/11/_update
{
   
   "script" : "ctx._source.num+=1"
}

result:
{
   
  "_index": "test_index",
  "_type": "test_type",
  "_id": "11",
  "_version": 2,
  "found": true,
  "_source": {
   
    "num": 1,
    "tags": []
  }
}

(2)外部脚本
脚本文件test-add-tags.groovy
ctx._source.tags+=new_tag

“file”: “test-add-tags”

POST /test_index/test_type/11/_update
{
   
  "script": {
   
    "lang": "groovy", 
    "file": "test-add-tags",
    "params": {
   
      "new_tag": "tag1"
    }
  }
}

(3)用脚本删除文档
脚本文件:test-delete-document.groovy
ctx.op = ctx._source.num == count ? ‘delete’ : ‘none’

POST /test_index/test_type/11/_update
{
   
  "script": {
   
    "lang": "groovy",
    "file": "test-delete-document",
    "params": {
   
      "count": 1
    }
  }
}

(4)upsert操作

POST /test_index/test_type/11/_update
{
   
  "doc": {
   
    "num": 1
  }
}


{
   
  "error": {
   
    "root_cause": [
      {
   
        "type": "document_missing_exception",
        "reason": "[test_type][11]: document missing",
        "index_uuid": "6m0G7yx7R1KECWWGnfH1sw",
        "shard": "4",
        "index": "test_index"
      }
    ],
    "type": "document_missing_exception",
    "reason": "[test_type][11]: document missing",
    "index_uuid": "6m0G7yx7R1KECWWGnfH1sw",
    "shard": "4",
    "index": "test_index"
  },
  "status": 404
}

如果指定的document不存在,就执行upsert中的初始化操作;如果指定的document存在,就执行doc或者script指定的partial update操作

POST /test_index/test_type/11/_update
{
   
   "script" : "ctx._source.num+=1",
   "upsert": {
   
       "num": 0,
       "tags": []
   }
}

partial update 内置乐观锁并发控制
partial update 内置乐观锁并发控制
retry_on_conflict
_version

post /index/type/id/_update?retry_on_conflict=5&version=6

2.16 mget 批量查询

1、批量查询的好处
就是一条一条的查询,比如说要查询100条数据,那么就要发送100次网络请求,这个开销还是很大的
如果进行批量查询的话,查询100条数据,就只要发送1次网络请求,网络请求的性能开销缩减100倍

2、mget的语法
(1)一条一条的查询

GET /test_index/test_type/1
GET /test_index/test_type/2

(2)mget批量查询

GET /_mget
{
   
   "docs" : [
      {
   
         "_index" : "test_index",
         "_type" :  "test_type",
         "_id" :    1
      },
      {
   
         "_index" : "test_index",
         "_type" :  "test_type",
         "_id" :    2
      }
   ]
}
result:
{
   
  "docs": [
    {
   
      "_index": "test_index",
      "_type": "test_type",
      "_id": "1",
      "_version": 2,
      "found": true,
      "_source": {
   
        "test_field1": "test field1",
        "test_field2": "test field2"
      }
    },
    {
   
      "_index": "test_index",
      "_type": "test_type",
      "_id": "2",
      "_version": 1,
      "found": true,
      "_source": {
   
        "test_content": "my test"
      }
    }
  ]
}

(3)如果查询的document是一个index下的不同type种的话

GET /test_index/_mget
{
   
   "docs" : [
      {
   
         "_type" :  "test_type",
         "_id" :    1
      },
      {
   
         "_type" :  "test_type",
         "_id" :    2
      }
   ]
}

(4)如果查询的数据都在同一个index下的同一个type下,最简单了

GET /test_index/test_type/_mget
{
   
   "ids": [1, 2]
}

3、mget的重要性
可以说mget是很重要的,一般来说,在进行查询的时候,如果一次性要查询多条数据的话,那么一定要用batch批量操作的api
尽可能减少网络开销次数,可能可以将性能提升数倍,甚至数十倍,非常非常之重要

2.17 bulk 批量增删改

1、bulk语法

POST /_bulk
{
    "delete": {
    "_index": "test_index", "_type": "test_type", "_id": "3" }} 
{
    "create": {
    "_index": "test_index", "_type": "test_type", "_id": "12" }}
{
    "test_field":    "test12" }
{
    "index":  {
    "_index": "test_index", "_type": "test_type", "_id": "2" }}
{
    "test_field":    "replaced test2" }
{
    "update": {
    "_index": "test_index", "_type": "test_type", "_id": "1", "_retry_on_conflict" : 3} }
{
    "doc" : {
   "test_field2" : "bulk test1"} }

每一个操作要两个json串,语法如下:

{
   "action": {
   "metadata"}}
{
   "data"}

举例,比如你现在要创建一个文档,放bulk里面,看起来会是这样子的:

{
   "index": {
   "_index": "test_index", "_type", "test_type", "_id": "1"}}
{
   "test_field1": "test1", "test_field2": "test2"}

有哪些类型的操作可以执行呢?
(1)delete:删除一个文档,只要1个json串就可以了
(2)create:PUT /index/type/id/_create,强制创建
(3)index:普通的put操作,可以是创建文档,也可以是全量替换文档
(4)update:执行的partial update操作

bulk api对json的语法,有严格的要求,每个json串不能换行,只能放一行,同时一个json串和一个json串之间,必须有一个换行

{
   
  "took": 41,
  "errors": true,
  "items": [
    {
   
      "delete": {
   
        "found": true,
        "_index": "test_index",
        "_type": "test_type",
        "_id": "10",
        "_version": 3,
        "result": "deleted",
        "_shards": {
   
          "total": 2,
          "successful": 1,
          "failed": 0
        },
        "status": 200
      }
    },
    {
   
      "create": {
   
        "_index": "test_index",
        "_type": "test_type",
        "_id": "3",
        "_version": 1,
        "result": "created",
        "_shards": {
   
          "total": 2,
          "successful": 1,
          "failed": 0
        },
        "created": true,
        "status": 201
      }
    },
    {
   
      "create": {
   
        "_index": "test_index",
        "_type": "test_type",
        "_id": "2",
        "status": 409,
        "error": {
   
          "type": "version_conflict_engine_exception",
          "reason": "[test_type][2]: version conflict, document already exists (current version [1])",
          "index_uuid": "6m0G7yx7R1KECWWGnfH1sw",
          "shard": "2",
          "index": "test_index"
        }
      }
    },
    {
   
      "index": {
   
        "_index": "test_index",
        "_type": "test_type",
        "_id": "4",
        "_version": 1,
        "result": "created",
        "_shards": {
   
          "total": 2,
          "successful": 1,
          "failed": 0
        },
        "created": true,
        "status": 201
      }
    },
    {
   
      "index": {
   
        "_index": "test_index",
        "_type": "test_type",
        "_id": "2",
        "_version": 2,
        "result": "updated",
        "_shards": {
   
          "total": 2,<
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值