Apache NiFi中ExtractText(正则提取)后合并属性的方法
解决方案:合并ExtractText多捕获属性为单个属性(NiFi v1.5.0)
针对你在NiFi 1.5.0中遇到的ExtractText多捕获属性合并需求,这里提供两种可行方案,按推荐程度排序:
方案1:使用ExecuteScript处理器(Groovy脚本)
这是最灵活且可靠的方案,尤其适合处理动态生成的带序号属性。
配置步骤:
- 添加一个
ExecuteScript处理器到你的流程中,放在ExtractText之后。 - 在处理器的Script Engine选择
Groovy。 - 在Script框中粘贴以下代码:
def flowFile = session.get() if (!flowFile) return // 定义要合并的属性前缀(这里是"date") def prefix = "date" def values = [] // 获取所有以指定前缀开头的属性 flowFile.attributes.each { key, value -> if (key == prefix || key.startsWith("${prefix}.")) { values.add(value) } } // 排序:确保无序号的date排在最前,带序号的按数字升序排列 def sortedValues = values.sort { a, b -> def keyA = flowFile.attributes.find { it.value == a }.key def keyB = flowFile.attributes.find { it.value == b }.key if (keyA == prefix) return -1 if (keyB == prefix) return 1 def numA = keyA.split("\\.")[1].toInteger() def numB = keyB.split("\\.")[1].toInteger() numA <=> numB } // 将排序后的结果合并为单个字符串,这里用逗号分隔,可根据需求修改分隔符 def merged = sortedValues.join(", ") // 添加新属性"dates",并移除原有的date系列属性(可选,按需保留) flowFile = session.putAttribute(flowFile, "dates", merged) flowFile.attributes.each { key, value -> if (key == prefix || key.startsWith("${prefix}.")) { flowFile = session.removeAttribute(flowFile, key) } } session.transfer(flowFile, REL_SUCCESS)
- 配置Relationships,确保
REL_SUCCESS指向后续流程。
自定义说明:
- 修改
prefix变量为你实际的属性前缀(比如如果是"email"就改成"email")。 - 修改
join(", ")中的分隔符,比如用换行符"\n"或者分号"; "。 - 如果需要保留原有的
date系列属性,可以删除代码中移除属性的那段逻辑。
方案2:使用UpdateAttribute处理器(纯表达式语言)
如果不想用脚本,也可以尝试用NiFi的表达式语言(EL)实现,但需要注意属性的数量是可预测的(或者用allAttributes遍历)。
配置步骤:
- 添加
UpdateAttribute处理器到ExtractText之后。 - 添加一个新的属性,名称为
dates,值填写以下EL表达式:
${join(filter(allAttributes, 'key matches "date(\\.\\d+)?"'), ", ")}
- (可选)如果需要移除原有的
date系列属性,可以在同一个UpdateAttribute中添加多个Delete Attribute规则,匹配date、date.*。
注意事项:
- 这个表达式会过滤所有以
date或date.数字开头的属性,然后用逗号分隔合并。 - NiFi 1.5.0的EL对
filter和join的支持是有效的,但如果属性数量非常多,可能不如脚本灵活。 - 合并后的顺序依赖于
allAttributes的遍历顺序,虽然ExtractText生成的属性是按数字升序,但allAttributes的顺序在NiFi中不保证严格一致,所以如果对顺序有严格要求,推荐方案1。
内容的提问来源于stack exchange,提问作者Joel Gooch
相关产品推荐
相关产品推荐

