Elasticsearch 删除数据

本文中,我们将学习几种删除数据的方法:

  • 删除单个文档或者一组文档。这样做的时候,Elasticsearch 只是将它们标记为删除,所以它们不会再出现于搜索结果中,
    稍后 Elasticsearch 通过异步的方式将它们彻底地从索引中移出。

  • 删除整个索引。这是删除多组文档的特例。但是不同点在于这样做的性能更好。
    主要的工作就是移除和那个索引相关的所有文件,几乎是瞬间就能完成。

  • 关闭索引。尽管这和删除无关,还是值得一提。关闭的索引不允许读取或者写入操作,数据也不会加载到内存。
    这和删除 Elasticsearch 数据类似,但是索引还是保留在磁盘上。它也很容易恢复,只要再次打开关闭的索引。

删除文档

有几种方式移除单个文档,这里讨论主要的几个。

  • 通过 ID 删除单个文档。如果只有一篇文档要删除,而且你知道它的 ID,这样做非常不错。

  • 在单个请求中删除多篇文档。如果有多篇文档需要删除,可以在一个批量请求中一次性删除它们,这样比每次只删除一篇文档更快。

  • 删除映射类型,包括其中的文档。这样的操作会高效地搜索并删除该类型中所索引的全部文档,也包括映射本身。

  • 删除匹配某个查询的所有文档。这和删除映射类型相似,内部运行一个查询,并识别需要删除的文档。只有在这里可以指定任何想要的查询,然后删除匹配的文档。

  1. 删除单个文档

为了删除单一的文档,需要向其 URL 发送 HTTP DELETE 请求。例如:

1
curl -XDELETE 'localhost:9200/online-shop/shirts/1'

也可以使用版本来管理删除操作的并发,就像索引和更新的并发控制一样。举个例子,假设某款衬衫销售一空,你想移除这篇文档,这样它就不会
出现在搜索结果中。但是当时你可能并不知道,新的采购到货了,而且库存数据也被更新了。为了避免这种情况,可以在 DELETE 请求中
加入版本 version 参数,就像索引和更新的操作那样。

尽管如此,删除的版本控制还是有个特殊情况。一旦删除了文档,它就不复存在了,于是一个更新操作很容易重新创建该文档,尽管这是不应该
发生的(因为更新的版本要比删除的版本更低)。由于外部版本可以用于不存在的文档上,使用外部版本时这个问题尤为突出。

为了防止这样的问题发生,Elasticsearch 将在一段时间内保留这篇文档的版本,如此它就能拒绝版本比删除操作更低的更新操作了。
默认情况下,这个时间是 60 秒,对于多数情况而应该足够了,但是你可以通过设置 elasticsearch.yml 文件中或者是每个索引配置中的
index.gc_deletes 来修改它。

  1. 删除映射类型和删除查询匹配的文档

你也可以删除整个映射类型,包括映射本身和其中索引的全部文档。要如此操作,需要向 DELETE 请求提供类型的 URL:

1
curl -XDELETE 'localhost:9200/online-shop/shirts'

删除类型时需要注意的是,类型名称只是文档中的另一个字段。索引中的所有文档,无论它们属于哪个类映射类型,都存放在同一个分片中。
当发送前面的命令时,Elasticsearch 只能查询属于哪个类型的文档,然后删除它们。当针对删除类型和删除完整索引两者的性能进行比较时,
这是很重要的细节。因为删除类型通常要耗费更长的时间和更多的资源。

以同样的方式,可以查询某个类型中所有的文档并删除它们,Elasticsearch 允许通过称为查询删除(delete by query)的 API 来指定自己的
查询,查找想要删除的文档。使用这个 API 和运行查询类似,除了 HTTP 请求变为 DELETE,而且 _search 的端点变为了 _query。

例如,为了从聚会索引 get-together 中移除所有匹配 “Elasticsearch” 的文档,可以运行这个命令:

1
curl -XDELETE 'localhost:9200/get-together/_query?q=elasticsearch'

和那些查询类似,可以通过查询特定的类型、多个类型、索引中的任何地方、多个索引甚至是整个索引,来运行一个删除操作。
在全部索引中查询时,通过查询的删除要特别小心。

删除索引

正如你所想,为了删除一个索引,需要发送一个 DELETE 请求到该索引的 URL:

1
curl -XDELETE 'localhost:9200/get-together'