ElasticSearch搜索有时无法搜索文档

时间:2019-07-01 06:48:17

标签: elasticsearch

我对ElasticSearch很陌生。我们使用默认配置ElasticSearch建立了一个具有5个分片的ElasticSearch节点。都是主要的分片,没有这样的复制。

我们在ElasticSearch中存储了一些与用户相关的信息。在一种用例中,我检查了弹性搜索中是否存在任何具有该移动电话号码的用户,并且是否将链接的用户或索引更新为新文档。

在某些情况下,我为同一用户收到很多重复的索引请求,因此此逻辑失败。它适用于大多数情况,但有时会失败。我无法深入探究这个问题

从我从文档中了解到的是,如果涉及到副本分片,则写入一致性,但就我而言,目前还没有副本分片。另外,在搜索过程中,elastic向所有分片发出请求,因此最终您应该获得文档。

我真的不明白为什么会失败。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

这可能是由于refresh设置所致。默认情况下,当您为文档编制索引时,该文档不能直接用于搜索,必须首先执行刷新操作。

也许您处于以下情况:

  1. 搜索用户X
  2. 没有匹配=>索引用户X
  3. 搜索用户X
  4. 由于仍未进行刷新而仍然没有匹配=>再次索引用户X
  5. 刷新

默认情况下,刷新操作每1秒发生一次,因此,如果两次搜索同一用户的时间少于1秒,则您很可能将文档索引两次。

如何避免这个问题?

如果可以为文档生成ID,则可以在更新api中使用doc_as_upsert参数。如果该文档不存在,则将创建该文档,否则将对其进行更新。

否则,您可以在每次搜索之前force a refresh索引。不建议这样做,因为刷新操作很繁琐,但是可以确保这是导致问题的原因。

请注意,由于索引操作可能会在force refresh操作和搜索操作之间进行,因此您仍将必须使用某些内部同步机制。例如,请参见以下情形:

  1. 线程1:刷新和搜索文档X =>没有结果
  2. 线程2:索引文档X
  3. 线程1:由于没有结果而对文档X进行搜索和索引

删除重复的文档

如果您同意在短时间内拥有一些重复的文档,则可以使用以下解决方案。

每次索引新文档时,您都会在数据结构中保留以下信息:

  • 索引请求的时间
  • 新索引文档的ID
  • 用于检查文档是否唯一的搜索查询
  • 一个标志,用于指示是否已再次搜索条目,并将其初始化为false

然后,您必须在每次刷新操作(默认情况下每秒)之后运行以下测试:

Foreach entry in the datastructure
  If indexationTime > now - refresh delay AND NOT entry.flag 
    // The indexed document corresponding to the entry is searchable
    entry.flag = true 
    // Avoid running the search another time
    Rerun the corresponding search query considering only the ids in the datastructure to speed up search.
    If there is multiple response, remove the duplicates 

要仅搜索一组选定的ID,可以使用ids query

您还必须从数据结构中删除可以安全丢弃的条目。也就是说,这些条目的标志设置为true,而所有其他在indexationTime + refreshDuration之前索引的其他条目的标志也都设置为true