Index API - shuiyuebingdian/ElasticSearch GitHub Wiki

索引API在特定索引中添加或更新类型化的JSON文档,使其可搜索。以下示例将JSON文档插入ID为1的“ tweet”类型下的“ twitter”索引中:

PUT twitter/tweet/1
{
	"user" : "kimchy",
	"post_date" : "2009-11-15T14:12:12",
	"message" : "trying out Elasticsearch"
}

以上索引操作的结果是:

{
	"_shards" : {
		"total" : 2,
		"failed" : 0,
		"successful" : 2
	},
	"_index" : "twitter",
	"_type" : "tweet",
	"_id" : "1",
	"_version" : 1,
	"created" : true,
	"result" : created
}

_shards报头提供关于索引操作的复制过程的信息。

  • total -指示应对索引操作执行多少个分片副本(主和副本分片)。
  • successful-指示索引操作成功进行的分片副本数。
  • failed -如果副本分片上的索引操作失败,则该数组包含与复制相关的错误。

在索引操作成功的情况下,successful至少为1。

索引操作成功返回时,副本碎片可能不会全部启动(默认情况下,仅需要主副本,但可以更改此行为)。在这种情况下, total它将等于基于该number_of_replicas设置的总分片,并且successful将等于已启动的分片数量(主加副本)。如果没有失败,failed则将为0。

自动索引创建

如果之前尚未创建索引操作,则索引操作会自动创建一个索引(请查看用于手动创建索引的 创建索引API),如果尚未创建索引的指定类型,也会自动创建一个动态类型映射dynamic type mapping(查看PUT mapping API,用于手动创建类型映射 type mapping)。

映射本身非常灵活并且没有架构。新的字段和对象将自动添加到指定类型的映射定义中。请查看映射 部分,以获取有关映射定义的更多信息。
[Mapping,就是对索引库中类型的字段名称及其数据类型进行定义,类似于mysql中的表结构信息]

通过在所有节点的配置文件中将设置action.auto_create_index为false,可以禁用自动创建索引 。自动映射创建可以通过设置被禁用 index.mapper.dynamic到false每个索引作为指标设置。

自动索引创建可以包括基于模式的白/黑列表,例如,设置action.auto_create_index为+aaa*,-bbb*,+ccc*,-*(+表示允许,-表示不允许)。

版本控制

每个索引的文档都有一个版本号。关联的 version数字作为对索引API请求的响应的一部分返回。当指定version参数时,索引API可选地允许 乐观并发控制。这将控制要针对其执行操作的文档的版本。版本控制用例的一个很好的例子是执行事务性的读后更新。从最初读取的文档中指定一个version 可以确保在此期间未发生任何更改(在进行读取以进行更新时,建议将其设置 preference为_primary)。例如:

PUT twitter/tweet/1?version=2
{
	"message" : "elasticsearch now has versioning support, double cool!"
}

注意:版本控制是完全实时的,几乎不受实时搜索操作的影响。如果未提供任何版本,则将执行该操作而不进行任何版本检查。

默认情况下,使用内部版本控制,该版本从1开始,并随着每次更新(包括删除)而递增。可选地,版本号可以附加一个外部值(例如,如果维护在数据库中)。要启用此功能,version_type应将其设置为 external。提供的值必须是大于或等于0且小于9.2e + 18左右的数字长值。使用外部版本类型时,系统将检查传递给索引请求的版本号是否大于当前存储文档的版本,而不是检查匹配的版本号。如果为true,将为文档建立索引并使用新的版本号。如果提供的值小于或等于存储的文档的版本号,则将发生版本冲突,并且索引操作将失败。

外部版本控制支持将值0作为有效版本号。这允许版本与外部版本控制系统同步,在外部版本控制系统中,版本号从零开始而不是一开始。副作用是,只要版本号等于零,就不能使用Update-By-Query API来更新版本号等于零的文档,也不能使用Delete by Query API来删除它们。

一个很好的副作用是,只要使用源数据库中的版本号,就不需要维护由于对源数据库进行更改而执行的异步索引操作的严格顺序。如果使用外部版本控制,即使使用数据库中的数据更新Elasticsearch索引的简单情况也得以简化,因为如果索引操作由于任何原因而失灵,则仅使用最新版本。

版本类型

除了上面解释的internal&external版本类型之外,Elasticsearch还支持其他用于特定用例的类型。这里是不同版本类型及其语义的概述。

internal
仅在给定版本与所存储文档的版本相同时才对文档建立索引。
external 或 external_gt
仅在给定版本严格高于存储文档的版本或没有现有文档的情况下才对文档建立索引。给定的版本将用作新版本,并将与新文档一起存储。提供的版本必须是非负长整数。
external_gte
仅在给定版本等于或高于存储文档的版本时对文档建立索引。如果没有现有文档,该操作也将成功。给定的版本将用作新版本,并将与新文档一起存储。提供的版本必须是非负长整数。

注意:external_gte版本类型适用于特殊使用情况,应谨慎使用。如果使用不正确,可能会导致数据丢失。还有一个force不推荐使用的选项,因为它可能导致主碎片和副本碎片分叉。

操作类型

索引操作还接受op_type可以用来强制执行create操作的,从而允许“如果不存在就新增”行为。当 create使用时,如果该ID在文档中的索引已经存在索引操作将失败。

这是使用op_type参数的示例:

PUT twitter/tweet/1?op_type=create
{
	"user" : "kimchy",
	"post_date" : "2009-11-15T14:12:12",
	"message" : "trying out Elasticsearch"
}

另一个指定选项create的方法是使用以下uri:

PUT twitter/tweet/1/_create
{
	"user" : "kimchy",
	"post_date" : "2009-11-15T14:12:12",
	"message" : "trying out Elasticsearch"
}

自动ID生成

无需指定id即可执行索引操作。在这种情况下,将自动生成一个id。此外,op_type 将自动设置为create。这是一个示例(请注意使用 POST代替PUT):

POST twitter/tweet/
{
	"user" : "kimchy",
	"post_date" : "2009-11-15T14:12:12",
	"message" : "trying out Elasticsearch"
}

以上索引操作的结果是:

{
	"_shards" : {
		"total" : 2,
		"failed" : 0,
		"successful" : 2
	},
	"_index" : "twitter",
	"_type" : "tweet",
	"_id" : "6a8ca01c-7896-48e9-81cc-9f70661fcb32",
	"_version" : 1,
	"created" : true,
	"result": "created"
}

路由

默认情况下,分片放置(或routing)是通过使用文档ID值的哈希值来控制的。为了进行更明确的控制,可以使用routing参数在每个操作的基础上直接指定馈入路由器使用的哈希函数的值。例如:

POST twitter/tweet?routing=kimchy
{
	"user" : "kimchy",
	"post_date" : "2009-11-15T14:12:12",
	"message" : "trying out Elasticsearch"
}

在上面的示例中,“ tweet”文档根据提供的routing参数“ kimchy” 被路由到分片。

设置显式映射时,_routing可以选择使用该字段来指示索引操作以从文档本身提取路由值。这确实需要额外的文档解析过程的(非常少的)成本。如果将_routing映射定义并设置为required,则在没有提供或提取路由值的情况下,索引操作将失败。

Parent & Children 可以在建立索引时通过指定其父项来建立子文档的索引。例如:

PUT blogs
{
  "mappings": {
	"tag_parent": {},
	"blog_tag": {
	  "_parent": {
		"type": "tag_parent"
	  }
	}
  }
}

PUT blogs/blog_tag/1122?parent=1111
{
	"tag" : "something"
}

索引子文档时,除非使用routing参数明确指定了路由值,否则路由值将自动设置为与其父文档相同。

分散式

索引操作基于其路由(请参见上面的“路由”部分)定向到主碎片,并在包含该碎片的实际节点上执行。主分片完成操作后,如果需要,会将更新分发到适用的副本。

等待活动碎片

为了提高写入系统的弹性,可以将索引操作配置为在继续操作之前等待一定数量的活动分片副本。如果必需数量的活动分片副本不可用,则写操作必须等待并重试,直到必需的分片副本已开始或发生超时为止。默认情况下,写入操作仅等待主要分片处于活动状态,然后再继续操作(即wait_for_active_shards=1)。可以通过设置在索引设置中动态覆盖此默认设置index.write.wait_for_active_shards。要更改每个操作的此行为,wait_for_active_shards可以使用request参数。

有效值是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
	}
}

刷新

控制何时可以看到此请求所做的更改。请参阅 刷新。

Noop更新

使用索引api更新文档时,即使文档没有更改,也会始终创建该文档的新版本。如果不可接受,请使用设置为true 的_updateapi detect_noop。此选项在索引api上不可用,因为索引api不会获取旧的源并且无法将其与新的源进行比较。

关于何时不可接受更新没有严格的规定。它综合了许多因素,例如您的数据源多久发送一次实际上是noop的更新以及每秒在接收到更新的分片上运行多少Elasticsearch查询。

超时

执行索引操作时,分配给执行索引操作的主分片可能不可用。造成这种情况的某些原因可能是主分片当前正在从网关恢复或正在进行重定位。默认情况下,索引操作将等待主碎片最多可用1分钟,然后失败并响应错误。该timeout参数可用于显式指定等待时间。这是将其设置为5分钟的示例:

PUT twitter/tweet/1?timeout=5m
{
	"user" : "kimchy",
	"post_date" : "2009-11-15T14:12:12",
	"message" : "trying out Elasticsearch"
}