应用"标记"数百万个文档,使用批量/更新方法

时间:2014-10-17 14:58:17

标签: search elasticsearch

我们在ElasticSearch实例中有大约55.000.000个文档。我们有一个带有user_ids的CSV文件,最大的CSV有9M条目。我们的文档以user_id为关键,这很方便。

我发布这个问题是因为我想讨论并且有最好的选择来完成这个,因为有不同的方法来解决这个问题。我们需要添加新的"标签"如果用户文档还没有使用它,例如使用" stackoverflow"来标记用户。或" github"。

  1. 有经典的partial update端点。这听起来很慢,因为我们需要迭代超过9M的user_ids并为每个用户发出api调用。
  2. bulk request,它提供了一些更好的性能,但在一次调用中可以提到的1000-5000个文档有限。并且知道批次何时太大,我们需要知道如何在旅途中学习。
  3. 然后/update_by_query端点official open issue有很多流量,但没有确认它是在标准版本中实现的。
  4. 在这个公开的问题上,提到了一个update_by_query plugin应该提供一些更好的处理,但是存在旧的和开放的问题,用户抱怨性能问题和内存问题。
  5. 我不确定它在EL上是否可行,但我认为我会将所有CSV条目加载到单独的索引中,并以某种方式加入这两个索引并应用将添加标记的脚本如果没有&# 39; t尚未存在。
  6. 所以问题仍然是最好的方法,如果有人在过去这样做了,请确保你分享你的数字/表现,以及你这次会做的不同。

5 个答案:

答案 0 :(得分:3)

在等待查询支持的更新时,我选择了:

  1. 使用scan/scroll API循环显示您要标记的文档ID(related answer)。

  2. 使用bulk API执行partial updates在每个匹配的文档上设置标记。

  3. 此外,我将标签数据(您的CSV)存储在单独的文档类型中,并从中查询并标记创建时的所有新文档,即不必先进行索引然后更新。

    Python片段来说明方法:

    def actiongen():
        docs = helpers.scan(es, query=myquery, index=myindex, fields=['_id'])
        for doc in docs:
            yield {
                '_op_type': 'update',
                '_index': doc['_index'],
                '_type': doc['_type'],
                '_id': doc['_id'],
                'doc': {'tags': tags},
            }
    
    helpers.bulk(es, actiongen(), index=args.index, stats_only=True)
    

答案 1 :(得分:2)

使用上述update-by-query plugin,您只需致电:

curl -XPOST localhost:9200/index/type/_update_by_query -d '{
    "query": {"filtered": {"filter":{
        "not": {"term": {"tag": "github"}}
    }}},
    "script": "ctx._source.label = \"github\""
}'

update-by-query插件只接受脚本,而不是部分文档。

至于性能和内存问题,我想最好是尝试一下。

答案 2 :(得分:0)

我应该使用批量API,但需要注意的是,您应尝试将每个文档更新为最少次数。更新只是原子删除,并添加并删除已删除的文档作为逻辑删除,直到它可以合并。

发送一个groovy脚本来执行更新可能在这里最有意义,所以你不必首先获取文档。

答案 3 :(得分:0)

您是否可以创建父/子关系,以便添加标记'引用您的帖子的类型'键入作为其父级。这样您就不需要对数据执行完全重新索引 - 只需根据相应的帖子ID将每个相应的标记编入索引。

答案 4 :(得分:0)

一个很老的线程。通过github页面登陆以实现“通过查询更新”以查看它是否在2.0中实现但不幸的是没有。感谢Teka的插件,如果更新很小,从感觉上非常可行,但我们的用例是基于某些复杂的查询每天更新数百万个文档。最后,我们转移到了es-hadoop连接器。虽然基础设施在这里是一个很大的开销,但是通过spark并行获取/更新/插入文档的过程无论如何帮助了我们。如果有人在过去一年中发现任何其他建议:),我很乐意听到。