Apache NiFi中Jolt转换:替换$oid嵌套值并保留其他字段
解决MongoDB ObjectId转ClickHouse的Jolt转换问题
在Apache NiFi数据管道中,从MongoDB读取数据写入ClickHouse时,MongoDB的ObjectId会以{"$oid": "xxx"}的嵌套结构出现在JSON中,导致ClickHouse写入异常。需要通过Jolt转换动态处理所有含$oid的字段:将父键直接替换为$oid对应的值,同时完整保留所有非$oid嵌套结构的字段。
当前使用的Jolt规则仅能提取出带$oid的字段,丢失了其他所有字段,无法满足需求。
示例输入
{ "_id": { "$oid": "67e3b577b9897ea76e00bd9e" }, "relationshipId": "67e3b541b9897ea76e007679-65316a69e9d1652da805b106-9810446605", "0To1Month": "", "groupId": { "$oid": "60d6e2b16bf83142a381f5fb" }, "groupLastAttemptDayAgo": 1742978685000, "nested": { "okdok": { "$oid": "60d6e2b16bf83142a381f5f9" } } }
期望输出
{ "_id" : "67e3b577b9897ea76e00bd9e", "relationshipId" : "67e3b541b9897ea76e007679-65316a69e9d1652da805b106-9810446605", "0To1Month" : "", "groupId" : "60d6e2b16bf83142a381f5fb", "groupLastAttemptDayAgo" : 1742978685000, "nested" : { "okdok" : "60d6e2b16bf83142a381f5f9" } }
现有Jolt规则(存在缺陷)
[ { "operation": "shift", "spec": { "*": { "\\$oid": "&1" } } } ]
该规则仅提取了_id、groupId两个带$oid的字段,丢失了其他所有字段。
正确的Jolt转换规则
需要使用递归处理+条件匹配的shift操作,同时覆盖所有层级的字段:
[ { "operation": "shift", "spec": { "*": { // 处理当前层级下的$oid字段:将父键替换为$oid的值 "\\$oid": "&1", // 处理非$oid的嵌套对象,递归保留结构 "*": { "\\$oid": "&2.&1", "*": "&2.&1.&" }, // 保留当前层级下的非嵌套非$oid字段 "@": "&" } } }, // 移除可能残留的空对象(可选,根据实际数据情况) { "operation": "remove", "spec": { "*": { "": "" } } } ]
规则解释
- 第一层shift操作:
\\$oid": "&1":匹配当前层级下的$oid字段,将父键(&1表示上一级的键名)替换为$oid的值。"*": { ... }:递归处理当前层级下的嵌套对象,对嵌套内部的$oid字段执行同样的替换逻辑(&2.&1表示保留父级路径)。"@": "&":直接保留当前层级下所有非嵌套、非$oid的原始字段。
- 第二层remove操作:可选步骤,用于清理转换后可能出现的空对象(如果原始数据中有空结构的话)。
内容的提问来源于stack exchange,提问作者tomsajuk
相关产品推荐
相关产品推荐

