ElasticSearch —修改ES数据
ElasticSearch能够以接近实时的速度提供数据操作和搜索功能。在默认情况下,从索引/更新/删除数据到出现在搜索结果之间,你可能会感受到有1秒的延迟时间(刷新间隔)。这是与SQL等其他平台的一个重要区别,这些平台在完成事务之后,它们的数据立即可用。
索引/替换文档
先前,我们已经知道如何索引一个单个的文档。我们可以再次回忆这个命令:
PUT/customer/external/1?pretty
{
"name":"John Doe"
}
同样,上述命令会将指定的文档索引至 customer
索引的“external”类型之中,它的ID是1。如果我们再次执行上述命令,但是使用不同的(或相同的)文档,那么ElasticSearch会将ID为1的已有文档替换(重新索引)为一个新的文档。
PUT/customer/external/1?pretty
{
"name":"Jane Doe"
}
上述命令会修改ID为1的文档的name字段,从“John Doe”修改为“Jane Doe”。另一方面,如果我们使用一个不同的ID,那么就会索引一个新的文档,并且索引中已有的文档会保持不变。
PUT/customer/external/2?pretty
{
"name":"Jane Doe"
}
上述命令会索引一个新的文档,它的ID为2。
当进行索引时,ID部分是可选的。如果没有指定,那么ElasticSearch将会生成一个随机的ID,然后用其索引文档。ElasticSearch生成的(或者我们在先前示例中明确指定的)真实ID是调用索引API的返回信息的一部分。
以下示例演示如何在没有显式ID的情况下对文档进行索引:
POST/customer/external?pretty
{
"name":"Jane Doe"
}
注意,在上面的例子中,我们使用的是 POST
命令,而不是 PUT
命令,因为我们没有指定任何ID。
更新文档
除了能够索引和替换文档之外,我们还可以更新文档。需要注意的是,ElasticSearch实际上在底层并没有立即执行更新操作。每当我们执行一次更新操作时,ElasticSearch就会删除旧的文档,然后索引一个新的文档,所有的更新内容都包含在这个新文档之中。
以下示例演示如何更新我们先前索引的文档(ID为1),将name字段修改为“Jane Doe”:
POST/customer/external/1/_update?pretty
{
"doc":{"name":"Jane Doe"}
}
以下示例演示如何更新我们先前索引的文档(ID为1),将name字段修改为“Jane Doe”,同时添加一个新的age字段:
POST/customer/external/1/_update?pretty
{
"doc":{"name":"Jane Doe","age":20}
}
你还可以使用简单脚本来执行更新操作。以下示例会使用一个脚本,将age字段增加5:
POST/customer/external/1/_update?pretty
{
"script":"ctx._source.age += 5"
}
在上述示例中, ctx._source
指的就是即将更新的当前源文档。
ElasticSearch还可以通过给定的查询条件更新多个文档(类似于SQL的 UPDATE-WHERE
语句)。请参考 更新查询API。
删除文档
删除文档是非常简单的。以下示例演示如何删除我们先前索引的ID为2的客户文档:
DELETE/customer/external/2?pretty
请参考 删除查询API,这样便能通过特定的查询删除所有匹配的文档。值得一提的是,删除一个完整的索引,相比起通过删除查询API来删除所有文档,效率要高得多。
批量处理
除了能够索引、更新和删除单个文档之外,ElasticSearch还提供了批量执行上述操作的功能,也就是名为<a href="https://www.elastic.co/guide/en/elasticsearch/reference/5.6/docs-bulk.html" title=" _bulk
“> _bulk
的API命令。这个功能非常重要,因为它能够提供一种非常高效的机制,可以尽量快地完成多个操作,同时尽量少地耗费网络往返的开销。
举个简单的例子,以下命令会在一个批量操作中索引两个文档(ID 1:John Doe和ID 2:Jane Doe):
POST/customer/external/_bulk?pretty
{"index":{"_id":"1"}}
{"name":"John Doe"}
{"index":{"_id":"2"}}
{"name":"Jane Doe"}
以下示例会在一个批量操作中更新第一个文档(ID为1),然后删除第二个文档(ID为2):
POST/customer/external/_bulk?pretty
{"update":{"_id":"1"}}
{"doc":{"name":"John Doe becomes Jane Doe"}}
{"delete":{"_id":"2"}}
注意,对于删除操作,在它之后没有相应的源文档,因为删除操作只需要待删除文档的ID就可以了。
批量操作的API命令不会由于其中某个动作失败而执行失败。如果某个动作由于某种原因而执行失败,API将继续处理后面的剩余动作。当批量操作的API命令返回时,它会显示每个操作的执行结果(和动作的发送顺序相同),这样你便能检查某个特定操作是否执行失败。