index API在特定索引中添加或更新JSON类型化文档,使其可搜索,下面的示例将JSON文档插入到“twitter”索引中,其类型名为“_doc”,id为1:数据库
PUT twitter/_doc/1 { "user" : "kimchy", "post_date" : "2009-11-15T14:12:12", "message" : "trying out Elasticsearch" }
以上索引操做的结果是:segmentfault
{ "_shards" : { "total" : 2, "failed" : 0, "successful" : 2 }, "_index" : "twitter", "_type" : "_doc", "_id" : "1", "_version" : 1, "_seq_no" : 0, "_primary_term" : 1, "result" : "created" }
_shards
报头提供了关于索引操做的复制过程的信息。api
total
- 指示应该对多少碎片副本(主碎片和副本碎片)执行索引操做。successful
- 指示成功执行索引操做的碎片副本的数量。failed
- 当副本碎片上的索引操做失败时,包含与复制相关错误的数组。索引操做成功的状况下,successful
至少是1。数组
当索引操做成功返回时,副本碎片可能不会所有启动(默认状况下,只须要主碎片,可是这种行为能够更改),在这种状况下,total
将等于基于number_of_replicas
设置的总碎片,successful
将等于启动的碎片数(主碎片加副本),若是没有失败,则failed
为0。
若是以前没有建立索引,则索引操做将自动建立索引(查看用于手动建立索引的create index API),而且若是尚未建立特定类型,还会自动为该类型建立动态类型映射(请参阅put mapping API以手动建立类型映射)。并发
映射自己很是灵活,而且没有模式,新的字段和对象将自动添加到指定类型的映射定义中,查看映射部分以得到关于映射定义的更多信息。app
能够经过在全部节点的配置文件中设置action.auto_create_index
为false
禁用自动索引建立,能够经过将index.mapper.dynamic
为每一个索引设置为false
来禁用自动映射建立。异步
自动索引建立能够包括基于白/黑名单列表的模式,例如,将action.auto_create_index
设置为+aaa*
、-bbb*
、+ccc*
、-*
(+
表示容许,-
表示不容许)。elasticsearch
每一个索引的文档都有一个版本号,关联的version
做为对index API请求的响应的一部分返回,当指定version
参数时,index API可选的容许乐观锁并发控制,这将控制要对其执行操做的文档的版本。版本控制用例的一个很好的例子是执行事务读 - 而后更新,指定一个从最初读取的文档中的version
,能够确保在此期间没有发生任何更改(当读是为了更新时,建议将preference
设置为_primary
),例如:函数
PUT twitter/_doc/1?version=2 { "message" : "elasticsearch now has versioning support, double cool!" }
注意:版本控制是彻底实时的,而且不受搜索操做的接近实时方面的影响,若是没有提供版本,则在不进行任何版本检查的状况下执行操做。oop
默认状况下,内部版本控制从1
开始,每次更新时递增,包括删除。可选地,版本号能够用外部值进行补充(例如,若是维护在数据库中),要启用该功能,应该将version_type
设置为external
。提供的值必须是一个数值,大于或等于0的long
值,并小于9.2e+18
。在使用外部版本类型时,系统检查传递给索引请求的版本号是否大于当前存储文档的版本号,而不是检查匹配的版本号,若是为true
,则对文档进行索引并使用新的版本号,若是提供的值小于或等于存储文档的版本号,将发生版本冲突,索引操做将失败。
外部版本控制支持将值
0
做为有效的版本号,这容许版本与版本号是从0开始而不是从1开始的外部版本控制系统同步。它的反作用是,版本号为0的文档既不能使用Update By Query API进行更新,也不能使用Delete By Query API进行删除,只要它们的版本号为0。
一个好的反作用是,只要使用了源数据库的版本号,就不须要维护因为更改源数据库而执行的异步索引操做的严格顺序。若是使用外部版本控制,那么即便使用数据库中的数据更新Elasticsearch索引的简单状况也会获得简化,由于若是索引操做因为某种缘由出现故障,则只使用最新版本。
除了上面介绍的internal
和external
版本类型以外,Elasticsearch还为特定的用例支持其余类型,下面是不一样版本类型及其语义的概述。
internal
external
或external_gt
long
数字。external_gte
long
数字。external_gte
版本类型用于特殊的用例,应该当心使用,若是使用不当,可能致使数据丢失,还有另外一个选项,force
,它被废弃了,由于它会致使主碎片和副本碎片分离。
索引操做还接受op_type
,可用于强制一个create
操做,容许“put-if-absent”的行为,使用create
时,若是该id文档已经存在于索引中,则索引操做将失败。
下面是一个使用op_type
参数的示例:
PUT twitter/_doc/1?op_type=create { "user" : "kimchy", "post_date" : "2009-11-15T14:12:12", "message" : "trying out Elasticsearch" }
指定create
的另外一个选项是使用如下uri:
PUT twitter/_doc/1/_create { "user" : "kimchy", "post_date" : "2009-11-15T14:12:12", "message" : "trying out Elasticsearch" }
能够在不指定id的状况下执行索引操做,在这种状况下,将自动生成id,此外,op_type
将被自动设置为create
,下面是一个例子(注意使用的是POST而不是PUT):
POST twitter/_doc/ { "user" : "kimchy", "post_date" : "2009-11-15T14:12:12", "message" : "trying out Elasticsearch" }
以上索引操做的结果是:
{ "_shards" : { "total" : 2, "failed" : 0, "successful" : 2 }, "_index" : "twitter", "_type" : "_doc", "_id" : "W0tpsmIBdwcYyG50zbta", "_version" : 1, "_seq_no" : 0, "_primary_term" : 1, "result": "created" }
默认状况下,碎片放置(或routing
)是经过使用文档的id
值的hash来控制的,为了实现更显式的控制,可使用routing
参数直接在每一个操做的基础上指定路由器使用的hash函数的值,例如:
POST twitter/_doc?routing=kimchy { "user" : "kimchy", "post_date" : "2009-11-15T14:12:12", "message" : "trying out Elasticsearch" }
在上面的示例中,“_doc”文档根据提供的routing
参数“kimchy”被路由到一个碎片。
在设置显式映射时,能够选择使用_routing
字段指导索引操做,从文档自己提取路由值,这确实须要额外的文档解析传递的成本(很是低),若是定义了_routing
映射并设置为required
,若是没有提供或提取到路由值,索引操做将失败。
索引操做根据其路由(请参阅上面的路由部分)定向到主碎片,并在包含此碎片的实际节点上执行,主碎片完成操做后,若是须要,更新将分发给合适的副本。
为了提升对系统的写操做的弹性,能够将索引操做配置为在继续操做以前等待必定数量的活动碎片副本,若是必需的活动碎片副本数量不可用,那么写操做必须等待并重试,直到必要的碎片副本启动或超时。默认状况下,写操做只等待主碎片处于活动状态后再继续(即wait_for_active_shards=1
),经过设置index.write.wait_for_active_shards
,能够在索引设置中动态覆盖此默认值,要更改每一个操做的这种行为,可使用wait_for_active_shards
请求参数。
有效值是all
或索引中每一个碎片中配置的副本总数的任意正整数(即number_of_replicas+1
),指定一个负数或一个大于碎片副本数量的数字会抛出错误。
例如,假设咱们有一个由三个节点组成的集群,A
、B
和C
,咱们建立一个索引,index
将副本的数量设置为3(结果是4个碎片副本,比节点多一个副本)。若是咱们尝试索引操做,默认状况下,操做只会在继续以前确保每一个碎片的主副本可用,这意味着,即便B
和C
宕机,而且A
托管主碎片副本,索引操做仍然只处理数据的一个副本。若是将wait_for_active_shards
设置为3
(全部3个节点都已启动),那么在继续以前,索引操做将须要3个活动碎片副本,这一要求应该获得知足,由于集群中有3个活动节点,每一个节点都持有碎片的副本。可是,若是咱们将wait_for_active_shards
设置为all
(或4
,这是相同的),索引操做将不会继续,由于索引中没有每一个活动碎片的全部4个副本,除非集群中出现一个新节点来承载碎片的第四个副本,不然操做将超时。
须要注意的是,这个设置大大减小了写操做不写入到所需碎片副本数量的机会,但它并无彻底排除这种可能性,由于这种检查发生在写操做开始以前,一旦写操做开始,复制仍然可能在任何数量的碎片副本上失败,但在主副本上仍然成功,写操做响应的_shards
部分显示复制成功/失败的碎片副本的数量。
{ "_shards" : { "total" : 2, "failed" : 0, "successful" : 2 } }
控制什么时候该请求所作的更改对搜索可见,参阅?refresh。
在使用索引api更新文档时,即便文档没有更改,也老是会建立文档的新版本,若是这是不可接受的,使用_update
api将detect_noop
设置为true
,这个选项在索引api上不可用,由于索引api不会获取旧源,而且没法将其与新源进行比较。
对于无操做的更新何时不可接受,并无硬性规定,它是许多因素的组合,好比数据源发送其实是无操做的更新的频率,以及每秒钟Elasticsearch在正在接收更新的碎片上运行多少查询。
当执行索引操做时,分配给执行索引操做的主碎片可能不可用,其中的一些缘由多是主碎片正在从网关中恢复或正在经历重定位。默认状况下,索引操做将等待主碎片变得可用1分钟,而后失败并响应错误,可使用timeout
参数显式地指定它的等待时间,这里有一个将其设置为5分钟的例子:
PUT twitter/_doc/1?timeout=5m { "user" : "kimchy", "post_date" : "2009-11-15T14:12:12", "message" : "trying out Elasticsearch" }