【问题标题】:ElasticSearch reindex nested field as new documentsElasticSearch 将嵌套字段重新索引为新文档
【发布时间】:2018-09-21 18:15:25
【问题描述】:
我目前正在更改我的 ElasticSearch 架构。
我以前在我的索引中有一个类型Product,其中包含一个嵌套字段Product.users。
我现在想要获得 2 个不同的索引,一个用于 Product,另一个用于 User,并在代码中建立两者之间的链接。
我使用reindex API 将我的所有Product 文档重新索引到新索引,使用脚本删除Product.users 字段:
ctx._source.remove('users');
但我不知道如何将我的所有 Product.users 文档重新索引到新的 User 索引,就像在脚本中一样,我将得到一个 users 的 ArrayList,我想为每个文档创建一个 User 文档.
有人知道如何实现吗?
【问题讨论】:
标签:
elasticsearch
nested
reindex
【解决方案1】:
对于可能面临这种情况的人,我最终使用scroll 和bulk API 重新索引users 嵌套字段。
- 我使用
scroll API 批量获取Product 文档
- 为每个批次迭代那些
Product 文档
- 为每个文档迭代
Product.users
- 创建一个新的
User 文档并将其添加到批量中
- 当我结束迭代
Product 批处理时发送批量
做好工作
【解决方案2】:
您需要的是 ETL(提取、转换、加载)。
大多数时候,编写一个完全符合您要求的小型 python 脚本更方便,但是,使用 elasticsearch,我喜欢一个:Apache Spark + elasticsearch4hadoop 插件。
此外,有时logstash 可以解决问题,但使用Spark 你有:
- SQL 语法或支持 Java/Scala/Python 代码
- 读/写 elasticsearch 非常快,因为分布式工作器(1 个 ES 分片 = 1 个 Spark 工作器)
- 容错(工人崩溃?没问题)
- 集群(如果您有数十亿个文档是理想的选择)
与 Apache Zeppelin(一个已打包并准备好 Spark 的笔记本)一起使用,您会喜欢的!
【解决方案3】:
我能想到的最简单的解决方案是运行 reindex 命令两次。一旦选择 Product 字段并重新索引到 newProduct 索引并为用户一次:
POST _reindex
{
"source": {
"index": "Product",
"type": "_doc",
"_source": ["fields", "to keep in", "new Products"]
"query": {
"match_all": {}
}
},
"dest": {
"index": "new_Products"
}
}
然后您应该能够通过仅在第二次重新索引中选择 Product.users 来在 new_User 表上再次重新索引