Apache NiFi Expression Language

Apache NiFi Expression Language(NiFi EL)是用于访问和操作FlowFile属性的强大工具,常用于数据处理和分发。它支持属性引用、函数调用、布尔逻辑、字符串和数字操作、日期处理等。用户可以利用EL对属性值进行比较、转换和组合,实现复杂的数据处理逻辑。NiFi EL的结构以${}包裹,属性搜索从FlowFile、Process Group变量、File Registry、JVM属性到操作系统环境变量。此外,NiFi提供了一个表达式语言编辑器帮助用户在配置处理器属性时使用和验证EL表达式。
摘要由CSDN通过智能技术生成

概览

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也非常容易。

NiFi 表达式的结构

NiFi表达式语言始终以开始定界符“ $ {”开始,并以结束定界符“}”结束。 在开始和结束定界符之间是表达式本身的文本。

最基本的形式,表达式可以只包含一个属性名称。 例如:$ {filename}将返回filename属性的值。

稍复杂的形势,可以调用一个函数对值进行处理再返回。例如:$ {filename:toUpper()} , 调用filename的toUpper函数,返回的是filename属性值的全大写形势。有编程经验的同学应该非常容易理解,这相当于在java代码“filename.toUpper();”,或者python代码的“filename.upper()”。我们拆解一下这个表达式:

  1. 调用方法使用的界定符是“:”
  2. 函数名称“toUpper”
  3. 函数的参数列表开始界定符"("
  4. 参数列表,这个例子里没有
  5. 函数的参数列表开始界定符")",这里也表示函数调用结束了。

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定义的特殊字符有:

  • $ (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})} ,这两个表达式的意思是一样的。但是属性名之间的空格是不会被忽略的,而且必须转义。

属性搜索层级

当NiFi el引用了一个属性名称时,NiFi都会去哪里搜索这个属性?

  1. 当前FlowFile的属性
  2. 搜索Process Group的变量
  3. 搜索File Registry file
  4. 搜索NiFi JVM的属性
  5. 搜索操作系统环境变量

NiFi由上到下逐一搜索,发现匹配的属性或者变量立即返回。如果没有搜索到则返回一个“null”。

el的使用

在NiFi应用程序中,el大量用于配置处理器属性,但是并非所有处理器属性都支持le。属性是否支持el,是由“Processor"的开发人员在编写处理器时决定。NiFi为每个属性清楚地标命了el是否被支持。

在NiFi配置组件属性时,用户界面在属性名称旁边提供一个信息图标([外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0Yq1CK67-1606194664025)(/Users/laofeng/Library/Mobile Documents/comappleCloudDocs/文稿/iconInfo-5929271.png)])。将鼠标悬停在该图标上,将提供一个提示,其中提供有关属性的有用信息。此信息包括属性的描述、默认值(如果有)、历史配置的值(如果有)以及表达式语言的此属性的计算范围。有三个值,表达式语言的求值范围是分层的:NONE(不支持) → VARIABLE_REGISTRY(变量注册表)→ FLOWFILE_ATTRIBUTES(FlowFile属性)。

  • None:此属性不支持使用el记性配置。
  • VARIABLE_REGISTRY: 按层次结构构造如下:
    • 在"Process Group"级别定义的变量,然后递归地向上到更高的"Process Group",直到根"Process Group"。
    • 在自定义属性文件(NiFi.properties)中通过nifi.variable.registry.properties注册的属性。
    • 在JVM级别定义的环境变量和系统属性。
  • FLOWFILE_ATTRIBUTES-将使用当前FlowFile的属性,以及变量注册表定义的变量。

转义

在NiFi EL中“ ” 和 “ ” 被 赋 予 特 别 的 意 义 , 因 此 如 果 P r o c e s s o r 属 性 中 要 使 用 这 个 两 个 标 记 作 为 文 本 意 义 时 则 需 要 进 行 转 义 。 例 如 , 用 户 可 能 希 望 将 属 性 值 配 置 为 文 本 “ H e l l o {”和“}”被赋予特别的意义,因此如果Processor属性中要使用这个两个标记作为文本意义时则需要进行转义。例如,用户可能希望将属性值配置为文本“Hello Processor使Hello{UserName}”,NiFi会将这段文本识别为EL表达式,这时候就需要使用转义,即添加一个额外的美元符号’’ " , 使 用 " H e l l o ",使用"Hello "使"Hello${UserName}"。转义本身比较简单,但是容易被忽略,而造成困扰,需要小心应对。

如果在{ 之前连续遇到两个以上的$字符,则每对$字符都将被视为$字符的转义。从左到右执行转义。为了帮助说明这一点,请考虑变量“abc”包含值“xyz”。然后,考虑下表中的表达式及其相应的求值:

表达式 返回值 说明
${abc} xyz
$${abc} ${abc} $ , 第 一 个 ,第一个 ,符为转义符号,第二个$被转义
$$${abc} $xyz
$$$${abc} $${abc}
$$$$${abc} $$xyz
I owe you $5 I owe you $5 没有el表达式
You owe me $$5 too You owe me $$5 too $字符没有转义,因为它不在el表达式前面。
Unescaped $$${5 because no closing brace Unescaped $$${5 because no closing brace 因为这里没有右大括号,所以没有实际的el表达式,因此$字符没有转义。
Unescaped $$${5} because no closing brace 此表达式无效,因为前两个美元符($ ) 因 为 转 义 在 文 本 上 等 于 一 个 美 元 ( )因为转义在文本上等于一个美元( )(),后跟“ 5 ” , 而 “ {5}”,而“ 5{5}”不是有效表达式。数字必须转义。正确的使用形
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值