【问题标题】:Cannot delete a document immediately after it is inserted?插入后无法立即删除文档?
【发布时间】:2021-04-29 06:37:50
【问题描述】:

我为我的 ElasticSearch 功能创建了一些测试,我注意到一些奇怪的行为。如果我有一个测试:

  1. 插入文档并确认没有错误
  2. 检索同一个文档,确认没有错误并确认它具有预期值
  3. 删除文档,确认没有错误并确认已删除 1 个文档

那么第三次测试将失败,因为 0 个文档被删除。如果我采取以下步骤之一:

  • 调试测试并在插入之后但删除之前放置断点
  • 在删除步骤之前添加time.Sleep(time.Second)

然后删除 1 个文档,第 3 次测试将通过。在第 3 次测试失败的情况下,我进入了我的 ES 实例并确认该文档存在。

这让我相信,在插入文档后,有一段时间必须发生一些事情,然后我才能删除该文档。

我的问题是 - 插入后需要做什么才能删除文档,在我的测试中是否有比休眠 1 秒更好的方法来处理这个问题?

我正在使用 Golang 进行编码,我正在使用 Olivere ES Client

【问题讨论】:

  • 这不太可能与 Go 有任何关系。插入调用返回后,Elastic 不保证一致性。

标签: go elasticsearch


【解决方案1】:

Elasticsearch 操作可能不一致。

如果适合您的测试,您可以选中 refreshwait_for_active_shards 选项。

注意:向不一致的系统添加测试总是很困难。

【讨论】:

    【解决方案2】:

    我不会使用inconsistence 这个词。存储和检索文档是real-time 操作。 search 发生在 near-real-time

    虽然您始终可以搜索文档,但只有在存在用于搜索的数据结构(通常是倒排索引)时,它们才会进入您的结果集中。为每个被索引的文档创建和维护这个数据结构成本高且效率低,这就是为什么最迟在刷新间隔到期时才创建数据结构的原因(默认刷新间隔为 1 秒)。

    此外,在删除文档时,该文档不会立即从磁盘中删除。它首先被标记为删除,以确保它不再出现在任何结果中。但只有在一些 Elasticsearch 内部管理(段合并)之后,标记为删除的文档最终才会被擦除。

    这应该让您知道为什么我们在搜索中谈论 near real-time 行为,或者您所说的“差距”

    特别是对于单元/集成测试,您需要确保在对文档进行索引后可以找到它。您可以通过添加参数refresh=wait_for 将您的索引/写入请求转换为阻塞请求来轻松实现此目的。这样,索引请求仅在创建搜索所需的数据结构之后返回。确保在您的下一个请求中,该文档可用于您要执行的任何操作。

    【讨论】:

      猜你喜欢
      • 2015-09-29
      • 2015-09-07
      • 2018-02-07
      • 2021-10-12
      • 2013-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多