for-each节点逻辑原理介绍

DataWorks为您提供遍历节点(for-each节点),您可以通过for-each节点来循环遍历赋值节点传递的结果集。同时您也可以重新编排for-each节点内部的业务流程。本文为您介绍for-each节点的组成与应用逻辑。

使用说明

您可通过以下内容了解遍历节点(for-each节点)的使用:

说明

相关文档

了解遍历节点(for-each节点)的使用场景。

应用场景

说明

仅用于遍历赋值节点传递的结果集。

了解遍历节点(for-each节点)使用限制与注意事项。例如,遍历次数上限、如何测试与查看日志。

使用限制注意事项

了解遍历节点(for-each节点)内部可根据业务需要自定义遍历节点内部业务流程,但要求待遍历业务流程开始节点需要为自带的Start节点,业务流程结束节点需要为节点自带的End节点。

节点组成与流程编排

了解遍历节点(for-each节点)遍历次数由赋值节点的输出决定。

遍历次数

了解遍历节点(for-each节点)提供的内置变量可获取每次遍历的相关值。

内置变量

提供遍历节点(for-each节点)的变量取值与遍历次数案例说明。

上游赋值节点为Shell时取值示例、上游赋值节点为ODPS SQL时取值示例

应用场景

DataWorks的for-each节点主要用于有循环遍历的场景,且需要与赋值节点联合使用,将赋值节点作为for-each节点的上游节点,将赋值节点的输出结果赋值给for-each节点后,一次次循环来遍历赋值节点的输出结果。

for-each

使用限制

  • 仅DataWorks标准版及以上版本支持使用for-each节点。详情请参见DataWorks各版本详解

  • for-each节点循环次数上限为1024次。实际遍历次数由赋值节点输出的结果集决定。

  • 不支持并发执行,即上次循环完成后才可进入下一次循环。

注意事项

维度

分类

说明

上下游依赖

依赖设置

for-each遍历节点需要遍历赋值节点传递的值,所以赋值节点需作为for-each节点的上游节点,for-each节点需要依赖赋值节点。

遍历支持

遍历次数上限

for-each节点最多支持循环1024次,如果超过了1024次,则运行会报错。实际循环遍历次数由上游赋值节点实际输出控制。

遍历次数

由赋值节点输出的结果集决定。

内部节点

流程编排

  • 您可以删除for-each节点的内部节点间的依赖关系,重新编排内部业务流程,但需要分别将Start节点End节点作为for-each节点内部业务流程的首末节点。

  • 在for-each节点的内部节点使用分支节点进行逻辑判断或者结果遍历时,需要同时使用归并节点

取值

提供内置变量来获取上游赋值节点的指定值。

调试运行

任务调试

  • DataWorks为标准模式时,不支持在DataStudio界面直接测试运行for-each节点。

    如果您想测试验证for-each节点的运行结果,您需要将包含for-each节点的任务发布提交到开发环境运维中心,在开发环境运维中心页面运行for-each节点任务。

  • 请同时执行赋值节点与for-each节点。在运维中心针对周期任务执行补数据操作时,请选择从赋值节点开始补数据,同时执行赋值节点与for-each遍历节点,勿单独执行for-each节点。

查看日志

在运维中心查看for-each节点的执行日志时,您需要右键实例,单击查看内部节点来查看内部节点的执行日志。

节点组成与流程编排

DataWorks的for-each节点是包含内部节点的一种特殊节点,您在创建完成for-each节点时,同时也自动创建完成了三个内部节点:Start节点(循环开始节点)、Shell节点(循环任务节点)、End节点(循环结束判断节点),通过内部节点组织成内部节点流程,实现对上游赋值节点输出结果的循环遍历。for-each内部节点如上图所示:

  • Shell节点

    DataWorks默认为您创建了一个Shell类型的内部任务运行节点,您也可以删除默认的Shell节点,自定义内部循环遍历任务的运行节点。

    • 若循环遍历任务为Shell类型,则可双击Shell节点,进入节点的代码开发页面开发任务代码。

    • 若循环遍历任务比较复杂,则可在内部节点流程中新建其他任务节点,根据实际情况重新构建节点的运行流程。

      说明

      自定义循环任务节点时,您可以删除内部节点间的依赖关系,重新编排循环节点内部业务流程,但需要分别将Start节点End节点作为for-each节点内部业务流程的首末节点。

  • Start节点End节点

    是内部节点业务流程每次循环遍历的开始节点与结束节点,不承载具体的任务代码。

    说明

    for-each节点的End节点不控制循环遍历的次数,for-each节点的循环遍历次数由上游赋值节点实际输出控制。

遍历次数

说明

for-each节点循环次数上限为1024次。实际遍历次数由赋值节点输出的结果集决定。

节点遍历次数由赋值节点输出的结果集决定:

  • Shell、Python遍历次数:按一维数组类型的输出,循环遍历次数即为一维数组元素的个数(按逗号切分)。

    例如,赋值节点的赋值语言为Shell或Python(Python2)时,输出结果为一维数组:2021-03-28,2021-03-29,2021-03-30,2021-03-31,2021-04-01,则for-each节点会循环5次完成遍历。

  • SQL类型遍历次数:按二维数组类型的输出,循环遍历次数即为二维数组元素的行数。

    例如,赋值节点的赋值语言为ODPS SQL时,输出结果为二维数组:

    +----------------------------------------------+
    | uid            | region | age_range | zodiac |
    +----------------------------------------------+
    | 0016359810821  | 湖北省 | 30~40岁   | 巨蟹座 |
    | 0016359814159  | 未知   | 30~40岁   | 巨蟹座 |
    +----------------------------------------------+

    则for-each节点会循环2次完成遍历。

内置变量

您可通过以下方式在遍历节点内部各节点获取遍历节点外部赋值节点的相关结果集。若遍历节点内部业务流程中存在赋值节点,您可以通过赋值节点下游默认取值方式在遍历节点内部进行取值。赋值节点下游取值方式请参见赋值节点

DataWorks的for-each节点每次循环遍历赋值节点的输出结果时,您可以通过一些内置的变量来获取当前已循环次数和偏移量。

内置变量

含义

与for循环对比

${dag.loopDataArray}

获取赋值节点的数据集

相当于for循环中的代码结果:

data=[]

${dag.foreach.current}

获取当前遍历值

以下面的for循环代码为例:

for(int i=0;i<data.length;i++) {
   print(data[i]);
}
  • data[i]相当于${dag.foreach.current}

  • i相当于${dag.offset}

${dag.offset}

当前偏移量(每一次遍历相对于第一次的偏移量)

${dag.loopTimes}

获取当前遍历次数

-

在您了解自己输出的表结构的情况下,您可以使用如下变量方式,获取其他变量取值。

其他变量

含义

${dag.foreach.current[n]}

上游赋值节点的输出结果为二维数组时,每次遍历时获取当前数据行的某列的数据。

${dag.loopDataArray[i][j]}

上游赋值节点的输出结果为二维数组时,获取数据集中具体i行j列的数据。

${dag.foreach.current[n]}

上游赋值节点的输出结果为一维数组时,获取具体某列数据。

内置变量取值案例

案例1:上游赋值节点为Shell节点

  • 赋值节点输出

    上游赋值节点为Shell节点,最后一条输出结果为2021-03-28,2021-03-29,2021-03-30,2021-03-31,2021-04-01

  • 遍历节点取值

    说明

    由于输出结果为一维数组,数组元素个数为5(逗号分隔每个元素),因此for-each总遍历次数为5。

    内置变量

    第1次循环遍历的取值

    第2次循环遍历的取值

    ${dag.loopDataArray}

    2021-03-28,2021-03-29,2021-03-30,2021-03-31,2021-04-01

    ${dag.foreach.current}

    2021-03-28

    2021-03-29

    ${dag.offset}

    0

    1

    ${dag.loopTimes}

    1

    2

    ${dag.foreach.current[3]}

    2021-03-30

案例2:上游赋值节点为ODPS SQL节点

  • 赋值节点输出

    上游赋值节点为ODPS SQL节点,最后一条select语句查询出两条数据:

    +----------------------------------------------+
    | uid            | region | age_range | zodiac |
    +----------------------------------------------+
    | 0016359810821  | 湖北省 | 30~40岁   | 巨蟹座 |
    | 0016359814159  | 未知   | 30~40岁   | 巨蟹座 |
    +----------------------------------------------+
  • 遍历节点取值

    说明

    由于输出结果为二维数组,数组行数为2,因此for-each总遍历次数为2。

    内置变量

    第1次循环遍历的取值

    第2次循环遍历的取值

    ${dag.loopDataArray}

    +----------------------------------------------+
    | uid            | region | age_range | zodiac |
    +----------------------------------------------+
    | 0016359810821  | 湖北省 | 30~40岁   | 巨蟹座 |
    | 0016359814159  | 未知   | 30~40岁   | 巨蟹座 |
    +----------------------------------------------+

    ${dag.foreach.current}

    0016359810821,湖北省,30~40岁,巨蟹座

    0016359814159,未知,30~40岁,巨蟹座

    ${dag.offset}

    0

    1

    ${dag.loopTimes}

    1

    2

    ${dag.foreach.current[0]}

    0016359810821

    0016359814159

    ${dag.loopDataArray[1][0]}

    0016359814159