PartitionRecord Processor
描述
根据数据中配置的字段拆分或分区面向记录的数据。 必须添加一项或多项属性。 属性的名称是要添加的属性的名称。 该属性的值是一个 RecordPath,用于针对每个 Record 进行评估。 仅当两个记录对于每个给定的 RecordPaths 具有相同的值时,它们才会进入相同的出站 FlowFile。 因为我们知道给定输出 FlowFile 中的所有记录对于 RecordPath 指定的字段都具有相同的值,所以为每个字段添加一个属性。 有关更多信息和示例,请参阅使用页面上的其他详细信息。
标签
使用场景
将记录分离到单独的 FlowFile 中,使每个 FlowFile 中的所有记录在给定字段或字段集上具有相同的值。
根据传入数据的格式选择合适的 RecordReader。
选择以所需输出格式写入数据的 RecordWriter。
添加一个额外的属性。该属性的名称应描述用于分区数据的数据类型。 该属性的值应是一个 RecordPath,用于指定 Record 属于哪个输出 FlowFile。
例如,如果我们想根据记录的 `transactionType` 字段来分离记录,我们可以添加一个名为 `transactionType` 的新属性。 该属性的值可以是 `/transaction/type`。然后,输入 FlowFile 将被分离为尽可能少的 FlowFiles,使每个 输出 FlowFile 的 `transactionType` 字段具有相同的值。
根据记录是否符合特定条件来分离记录
根据传入数据的格式选择合适的 RecordReader。
选择以所需输出格式写入数据的 RecordWriter。
添加一个额外的属性。该属性的名称应描述该条件。 该属性的值应是一个 RecordPath,当 Record 满足条件时返回 `true`,否则返回 `false`。
例如,如果我们想根据记录的交易总额是否超过 $1,000 来分离记录,我们可以添加一个名为 `largeTransaction`、值为 `/transaction/total > 1000` 的新属性。这将创建两个 FlowFiles。在第一个中,所有记录的总额都将超过 `1000`。 在第二个中,所有记录的交易都将小于或等于 1000。每个 FlowFile 都将有一个名为 `largeTransaction` 的属性,其值为 `true` 或 `false`。
属性
| 名称 | 默认值 | 可选值 | 描述 |
|---|---|---|---|
| Record Reader | | 控制器服务 API:RecordReaderFactorycn.org.acal.lynxus-lynxus-standard-services-api-nar-2.11.8 | 指定用于读取传入数据的 Controller Service |
| Record Writer | | 控制器服务 API:RecordSetWriterFactorycn.org.acal.lynxus-lynxus-standard-services-api-nar-2.11.8 | 指定用于写出记录的 Controller Service |
动态属性
| 名称 | 值 | 描述 |
|---|---|---|
| 赋予动态属性的名称即为用于表示关联 RecordPath 值的属性的名称。 | 指向 Record 中某个字段的 RecordPath。 | 每个动态属性表示一个 RecordPath,将针对传入 FlowFile 中的每条记录进行评估。当确定记录的 RecordPath 值时,将向输出 FlowFile 添加一个属性。属性名称与此属性的名称相同。属性值与 RecordPath 指向的记录中字段的值相同。请注意,如果 RecordPath 返回的值为 null 或不是标量值(即值为 Array、Map 或 Record),则不会添加属性。 |
关系 (Relationships)
| 名称 | 描述 | 自动终止 |
|---|---|---|
failure | 如果 FlowFile 无法从配置的输入格式分区为配置的输出格式,未更改的 FlowFile 将被路由到此关系 | 否 |
original | 一旦传入 FlowFile 中的所有记录都已分区,原始 FlowFile 就会路由到此关系。 | 否 |
success | 成功分区的FlowFile将被路由到此关系 | 否 |
写入的 FlowFile 属性
| 名称 | 描述 |
|---|---|
record.count | 传出 FlowFile 中的记录数 |
mime.type | 配置的Record Writer指示的 MIME 类型是适当的 |
fragment.identifier | 从同一父 FlowFile 产生的所有分区 FlowFile 将添加相同的随机生成 UUID 作为此属性 |
fragment.index | 一个单数,指示从单个父 FlowFile 创建的分区 FlowFile 的顺序 |
fragment.count | 从父FlowFile生成的分区FlowFile的数量 |
segment.original.filename | 父FlowFile的文件名 |
<dynamic property name> | 对于添加的每个动态属性,可以将属性添加到FlowFile。 有关详细信息,请参阅动态属性的描述。 |
状态管理
该组件不存储状态。
受限 (Restricted)
该组件不受限。
输入要求
该组件要求有传入连接。
详细说明
PartitionRecord
PartitionRecord 允许用户把 FlowFile 中的记录分离出去,使每个输出 FlowFile 只包含彼此"相似"的 记录。为了定义两条记录怎样才算相似,该 Processor 使用 Lynxus 的 RecordPath DSL。
要使 Processor 有效,至少要为它添加一个用户自定义属性,属性值必须是合法的 RecordPath。 支持表达式语言(Expression Language),并会在尝试编译 RecordPath 之前先对其求值。 不过,如果使用了表达式语言,Processor 无法事先校验 RecordPath,若使用时 RecordPath 不合法,可能导致 FlowFile 处理失败。
添加一个或多个 RecordPath 之后,这些 RecordPath 会对传入 FlowFile 中的每条记录求值。 要使记录 A 与记录 B 被视为"相似记录",它们在所有已配置的 RecordPath 上必须具有相同的值。 只有 RecordPath 返回的值会保存在 Java 堆中,记录本身会立即写入 FlowFile 内容。这意味着在 大多数情况下不必担心堆的使用。但是,如果 RecordPath 指向一个在 FlowFile 内每条记录都 不同的大型 Record 字段,堆的使用就可能成为一个重要考量。在这种情况下,可以借助 SplitRecord 在分区之前把大 FlowFile 拆分成较小的 FlowFile。
一旦写出某个 FlowFile,我们就知道该 FlowFile 内的所有记录在已配置 RecordPath 所描述的
字段上具有相同的值。因此可以把这些值提升为 FlowFile Attribute。做法是查看每个
RecordPath 所归属的属性名。例如,如果有一个名为 country、值为 /geo/country/name
的属性,那么每个输出 FlowFile 都会有一个名为 country、值为 /geo/country/name
字段值的 Attribute。添加这些 Attribute 使得执行路由等任务,或者在另一个可用于配置数据
发送目的地的 Processor 中引用该值,都变得非常容易。不过,对于值不是标量的
RecordPath(即值的类型为 Array、Map 或 Record),不会添加 Attribute。
示例
为了更好地理解该 Processor 的工作方式,我们给出几个示例。为了便于说明,假设输入数据是 JSON 格式,内容如下:
[
{
"name": "John Doe",
"dob": "11/30/1976",
"favorites": [
"spaghetti",
"basketball",
"blue"
],
"locations": {
"home": {
"number": 123,
"street": "My Street",
"city": "New York",
"state": "NY",
"country": "US"
},
"work": {
"number": 321,
"street": "Your Street",
"city": "New York",
"state": "NY",
"country": "US"
}
}
},
{
"name": "Jane Doe",
"dob": "10/04/1979",
"favorites": [
"spaghetti",
"football",
"red"
],
"locations": {
"home": {
"number": 123,
"street": "My Street",
"city": "New York",
"state": "NY",
"country": "US"
},
"work": {
"number": 456,
"street": "Our Street",
"city": "New York",
"state": "NY",
"country": "US"
}
}
},
{
"name": "Jacob Doe",
"dob": "04/02/2012",
"favorites": [
"chocolate",
"running",
"yellow"
],
"locations": {
"home": {
"number": 123,
"street": "My Street",
"city": "New York",
"state": "NY",
"country": "US"
},
"work": null
}
},
{
"name": "Janet Doe",
"dob": "02/14/2007",
"favorites": [
"spaghetti",
"reading",
"white"
],
"locations": {
"home": {
"number": 1111,
"street": "Far Away",
"city": "San Francisco",
"state": "CA",
"country": "US"
},
"work": null
}
}
]
示例 1 - 按简单字段分区
举一个简单的例子,按记录所居住的州(state)对所有记录进行分区。可以添加一个名为
state、值为 /locations/home/state 的属性。结果会产生两个输出 FlowFile。第一个
包含一个名为 state、值为 NY 的 Attribute,由 3 条记录组成:John Doe、Jane Doe
和 Jacob Doe。第二个 FlowFile 只包含 Janet Doe 一条记录,并包含一个名为 state、
值为 CA 的 Attribute。
示例 2 - 按可为 null 的值分区
在上面的示例中,工作地点(work location)有三个不同的值。如果使用属性名 state、
值为 /locations/work/state 的 RecordPath,会得到两个不同的 FlowFile。第一个包含
John Doe 和 Jane Doe 的记录,因为它们在给定 RecordPath 上具有相同的值。该
FlowFile 会有一个名为 state、值为 NY 的 Attribute。
第二个 FlowFile 包含 Jacob Doe 和 Janet Doe 两条记录,因为该 RecordPath 对两者
求值都为 null。该 FlowFile 不会有 state Attribute(除非传入 FlowFile 上原本就
存在这样的 Attribute,此时其值保持不变)。
示例 3 - 按多个值分区
现在假设我们想根据多个不同的字段对记录进行分区。我们给 PartitionRecord Processor
添加两个属性:第一个名为 home,值为 /locations/home;第二个名为 favorite.food,
值为 /favorites[0],用于引用 "favorites" 数组的第一个元素。
这会产生三个不同的 FlowFile。第一个包含 John Doe 和 Jane Doe 的记录,并包含一个 名为 "favorite.food"、值为 "spaghetti" 的 Attribute。不过,由于第二个 RecordPath 指向的是一个 Record 字段,不会添加 "home" Attribute。在这个例子中,这两条记录的 "favorites" 数组第一个元素和家庭住址都相同。Janet Doe 的 "favorites" 数组第一个 元素相同,但家庭住址不同;同样地,Jacob Doe 的家庭住址相同,但最喜欢的食物不同。
第二个 FlowFile 只包含一条记录:Jacob Doe。该 FlowFile 会有一个名为 "favorite.food"、值为 "chocolate" 的 Attribute。第三个 FlowFile 只包含一条记录: Janet Doe。该 FlowFile 会有一个名为 "favorite.food"、值为 "spaghetti" 的 Attribute。