用ADF做数据集成的人,迟早会遇到这样一个场景:上游目录里堆了一堆文件,但管道只想处理其中符合规则的那几个。比如只加载当天生成的CSV,或者只处理文件名里带某个关键字的订单文件。如果在ForEach环节把目录里所有文件都拉进来,轻则做一堆无用功,重则因为混入了临时文件、隐藏文件、文件夹,直接把下游数据搞脏。Azure Data Factory里的Filter活动,就是专门用来在管道内做这一层“条件过滤”的。
Filter活动在ADF里的定位很纯粹:它接收一个数组,按你写的布尔表达式对数组里的每个元素做判断,最后只把满足条件的元素吐出来。听起来不复杂,但实际用起来有不少讲究——Items怎么填、Condition怎么写、返回结果是什么结构、和后继的ForEach怎么衔接,包括日期比较、类型转换、大小判断这些细节,都直接影响管道能不能一次跑通。这篇文章不绕弯子,直接从痛点、配置、实操到常见坑,把Filter活动讲透。
1. Filter活动解决的痛点与核心定位
1.1 为什么管道里需要“先过滤再处理”
数据集成管道里最常见的矛盾,是“源端的文件永远比你想的多”。一个落地目录里,可能有上游业务系统按小时生成的正式数据文件,也可能有运维放的说明文档、临时导出的备份、半成品目录,甚至还有以.开头的隐藏文件。如果把这堆东西全部交给ForEach去轮询,要么多跑大量无意义的Copy活动,要么在下游解析时炸出格式错误。
我习惯把Filter看成“管道里的分拣员”。就像快递分拨中心不会把每个包裹都直接送上干线运输车,而是先按面单上的目的地区域做一次分拣;ADF管道在进入ForEach循环之前,也应该先筛选出真正需要处理的文件列表。这个思路的收益在文件量大、来源复杂时特别明显——一次过滤,后面所有的循环体活动都能少跑一批无用功。
1.2 Filter活动在ADF“活动家族”中的位置
在ADF管道的活动面板里,Filter活动被归类在“Iteration & conditionals”这个分组下。和它经常一起出现的是ForEach、If Condition、Until这些流程控制活动。Filter和它们最大的区别是:它不对管道分支进行控制,也不产生“执行副作用”,它只负责“计算并输出一个数组”。
这个特性让Filter非常安全。你把它放在管道里,即便条件写错了,最多是输出结果不对,不会像Copy Data活动那样真的去移动或转换数据。我经常用这个特性来“试探性”地输出文件清单,先看Filter的输出,再决定下一步怎么处理。这是它的核心定位:一个纯计算、纯转换的数组处理器。
1.3 和Get Metadata的搭配逻辑
Filter活动自己不会凭空产生文件列表,它的上游几乎固定是Get Metadata活动。Get Metadata负责从数据源读取元数据,比如一个目录下的所有子项(childItems);Filter则在那份清单上做条件筛选。两者拼在一起,就构成了ADF里处理文件列表的“标准套餐”。
实际操作中,Get Metadata的字段参数要勾选Child items,输出是一个数组,数组里的每个元素通常包含name、type、size、lastModified这些属性。Filter的Items直接指向@activity('Get Metadata1').output.childItems,然后Condition里用item().name、item().size、item().lastModified来写判断逻辑。这几乎覆盖了所有文件过滤场景。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Filter活动两大核心参数:Items与Condition
2.1 Items:往Filter里喂一个数组
Filter活动的配置界面很简单,核心就两个字段:Items和Condition。Items填写的是“待过滤的数组”,它的常见来源有三种。
第一种,也是最常见的,是直接引用Get Metadata的输出。第二种是从管道参数或者变量里来,比如某个Lookup活动返回的查询结果集,你想在进入ForEach前先按条件剔除一部分。第三种是手动构建一个数组字面量,比如@json('[{"name":"a.txt","size":10},{"name":"b.csv","size":20}]'),这在调试表达式时很有用。
在使用Items时有一个很容易忽略的细节:它必须是数组类型。如果你的表达式返回的是一个对象而不是数组,比如直接写@activity('Get Metadata1').output,Filter会直接报错,提示无法将对象转换为数组。正确写法是后面带上.childItems或者.value这类数组属性。
2.2 Condition:用表达式描述“留下谁”
Condition字段是Filter活动的灵魂,它接收一个布尔表达式,表达式的返回结果必须是true或false。表达式里通过item()来引用数组里的当前元素。我这里总结了几类最常用的条件写法,几乎覆盖了日常文件过滤的绝大部分需求。
json复制// 按文件名后缀过滤,只保留CSV
@endswith(item().name, '.csv')
// 按文件名前缀过滤,只保留订单文件
@startswith(item().name, 'or
