【Apache NIFI 翻译】4-Apache NiFi Expression Language Guide 表达式语言
原文地址:http://nifi.apache.org/docs.html
参考博客:https://blog.csdn.net/tj85771370/article/details/110069708
Overview
NiFi主要的功能是数据处理和数据分发,在NiFi中数据均抽象为FlowFile。FlowFile有两个部分组成:内容(Content)和属性(attribute)。这里Content是实际上要处理和分发的数据,而FlowFile并不直接存储数据而是存储了一个指向实际存储地址的指针。属性(attribute)是数据本身相关的元数据,描述信息等,形式是一组键值对。例如:“GetFile Processor”从本地磁盘中读取文件,则文件内容将成为FlowFile的内容,则属性可能为文件名、文件目录、文件大小、最后修改时间、读写权限等。FlowFile的属性使我们在不需要读取数据内容的情况下,能够完成很多数据处理操作。NiFi引入Expression Language就是为了使用户能够方便的访问FlowFile的属性,对它们进行引用、比较、赋值等操作。如果使用过其他表达式语言例如:spring el或者jsp el,那么掌握NiFi el将非常容易。如果有开发经验,掌握NiFi el也非常容易。
Structure of a NiFi Expression
NiFi表达式语言始终以开始定界符“ $ {”开始,并以结束定界符“}”结束。 在开始和结束定界符之间是表达式本身的文本。
最基本的形式,表达式可以只包含一个属性名称。 例如:$ {filename}将返回filename属性的值。
稍复杂的形势,可以调用一个函数对值进行处理再返回。例如:$ {filename:toUpper()} , 调用filename的toUpper函数,返回的是filename属性值的全大写形势。有编程经验的同学应该非常容易理解,这相当于在java代码“filename.toUpper();”,或者python代码的“filename.upper()”。我们拆解一下这个表达式:
- 调用方法使用的界定符是“:”
- 函数名称“toUpper”
- 函数的参数列表开始界定符"("
- 参数列表,这个例子里没有
- 函数的参数列表开始界定符")",这里也表示函数调用结束了。
NiFi el语言提供了很多的函数(这里基本对应了java的各种函数),用于应对各种各样的需求。例如操作字符串的toUpper(转大些)、equals(比较)、matches(正则匹配)等功能,另外还提供了丰富的数学计算和时间、日期操作函数。我们在一个属性上执行函数时,将这个属性称为函数的“subject”,因为函数是在属性实体上运行的。
这里可以类比java函数调用。函数的调用时依赖于一个对象的,通常是object.xxx();在nifi里属性就是这个object。
链式调用
在NiFi el中,可以链式调用函数,形式是这样的${filename:toUpper():equals(‘HELLO.TXT’)}。在这个例子中“filename”是toUpper的“subject”,toUpper的返回值是equals的“subject”。链接在一起调用的功能函数的数量没有限制。
这里必须明确每个函数返回值的类型,因为返回值类型决定了下一个步能够使用什么函数。filename是一个字符串,能够使用字符串处理的函数toUpper, toUpper函数返回的也是字符串,能够继续是用字符串比较函数equals,equals函数返回的是一个boolean,这是就不能再调用字符串函数了,只能调用Boolean类型的函数。
字符转义
任何FlowFile的属性都可以被NiFi el引用。但是如果属性名称包含特殊字符,则必须对该属性名称进行转义。NiFi el定义的特殊字符有:
- List item
- $ (dollar sign)
- | (pipe)
- { (open brace)
- } (close brace)
- ( (open parenthesis)
- ) (close parenthesis)
- [ (open bracket)
- ] (close bracket)
- , (comma)
- : (colon)
- ; (semicolon)
- / (forward slash)
-
- (asterisk)
- ’ (single quote)
- (space)
- \t (tab)
- \r (carriage return)
- \n (new-line)
此外,如果属性名称的第一个字符是数字,则它也被视为"特殊字符"。如果属性名称中存在特殊字符,则需要将属性名称至于双引号或者单引号之间。在NiFi el中双引号和单引号有等同的作用,可以互换使用。例如:一个属性名称“my attribute”中有空格,则在使用中应该转义,而使用${“my attribute”}
或${'my attribute'}
这两种形式都是对的。
在本例中,要返回的值是“my attribute”属性的值(如果存在)。表达式语言将在一个层次结构中搜索匹配的属性。层次结构在下文中详细介绍。
还有一些函数是没有“subject”的,类似于java的静态函数没有对象就能调用。这些函数需在表达式开始进行调用,例如${hostname()}
。这些功能也可以一起改变。例如,${hostname():toUpper()}
。尝试使用“subject”调用这些函数将导致错误。
嵌入式表达式
如果需要比较两个不同属性的值,可以通过嵌入式表达式来实现这一点。例如,检查“filename”属性是否与“uuid”属性相同:${filename:equals( ${uuid})}
。特别注意,在“equals”函数的左括号和嵌入表达式之间有一个空格,这不影响表达式的计算,它的目的是使表达式更易于阅读。分隔符之间的空白会被el忽略。因此,我们可以使用表达式${ filename : equals(${ uuid}) }
或 ${filename:equals(${uuid})}
,这两个表达式的意思是一样的。但是属性名之间的空格是不会被忽略的,而且必须转义。
Expression Language Hierarchy
当NiFi el引用了一个属性名称时,NiFi都会去哪里搜索这个属性?
- List item
- 当前FlowFile的属性
- 搜索Process Group的变量
- 搜索File Registry file
- 搜索NiFi JVM的属性
- 搜索操作系统环境变量
NiFi由上到下逐一搜索,发现匹配的属性或者变量立即返回。如果没有搜索到则返回一个“null”。
Expression Language in the Application
待续。