我有一个包含多个重复条目的索引。它们具有不同的ID,但其他字段具有相同的内容。
例如:
{id: 1, content: 'content1'}
{id: 2, content: 'content1'}
{id: 3, content: 'content2'}
{id: 4, content: 'content2'}
删除重复项后:
{id: 1, content: 'content1'}
{id: 3, content: 'content2'}
有没有办法删除所有重复项并只保留一个不同的条目而不手动比较所有条目?
答案 0 :(得分:2)
我使用rails,如果需要,我将使用FORCE=y
命令导入内容,该命令会删除并重新索引该索引的所有内容并输入...但是不确定您运行ES的环境是什么。只有问题我可以看到你导入的数据源(即数据库)是否有重复的记录。我想我会首先看到数据源是否可以修复,如果可行,你重新索引所有内容;否则,您可以尝试创建一个自定义导入方法,该方法仅为每条记录索引一个重复项目。
此外,我知道这并不符合你想要删除重复条目,但你可以简单地自定义你的搜索,这样你只能返回一个重复的id,或者是最近的#34 ;时间戳"或索引重复数据删除的数据并按内容字段进行分组 - 请参阅this post helps。即使这仍然会保留索引中的重复记录,但至少他们不会在搜索结果中出现。
我也发现了这一点:Elasticsearch delete duplicates
我尝试了很多可能的场景,看看这些选项是否有效或者至少可以成为临时解决方案。
答案 1 :(得分:1)
这可以通过多种方式来完成。下面我概述了两种可能的方法:
1)如果您不介意生成新的_id
值并将所有文档重新索引到一个新的集合中,则可以使用Logstash和fingerprint过滤器来生成唯一的指纹(哈希)从您要删除重复数据的字段中删除,并在将文档写入新集合时将其用作文档的_id
指纹。由于_id
字段必须唯一,因此具有相同指纹的任何文档都将写入相同的_id
,因此将进行重复数据删除。
2)您可以编写一个自定义脚本来滚动索引。读取每个文档时,您可以从考虑用来定义唯一文档的字段(在您的情况下为content
字段)中创建哈希。然后使用此哈希,因为它们键入字典(又名哈希表)。与此键关联的值将是生成该相同哈希的所有文档_id
的列表。一旦拥有_id
的所有散列和关联列表,就可以对与每个相同散列关联的_id
以外的所有MutableMap
执行删除操作。请注意,第二种方法不需要将文档写入新索引即可进行重复数据删除,因为您可以直接从原始索引中删除文档。
我已经在以下URL上写了一篇博客文章和代码来演示这两种方法:https://alexmarquardt.com/2018/07/23/deduplicating-documents-in-elasticsearch/
免责声明:我是Elastic的一名咨询工程师。