Lambda 事件筛选 - Amazon Lambda
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

Lambda 事件筛选

对于 Amazon Kinesis、Amazon DynamoDB 和 Amazon Simple Queue Service(Amazon SQS)事件源,您可以使用事件筛选来控制 Lambda 发送给函数进行处理的事件。例如,您可以定义筛选条件,以便仅处理具有状态代码 ERROR 的 Kinesis 流中的记录。

您可以为单个事件源定义最多五个不同的筛选条件。如果事件满足这五个筛选条件中的任意一个,则 Lambda 会将事件发送到您的函数。否则,Lambda 会丢弃该事件。事件要么符合筛选条件,要么不符合筛选条件。如果您使用的是批处理时段,则 Lambda 会对每个新事件应用筛选条件,以确定是否将其添加到当前批处理中。

事件筛选基础知识

筛选条件 (FilterCriteria) 对象是一个由筛选条件 (Filters) 列表组成的结构。每个筛选条件 (Filter) 是一个用于定义事件筛选模式 (Pattern) 的结构。Pattern 是 JSON 筛选条件规则的字符串表示。FilterCriteria 对象与以下示例类似:

{ "Filters": [ { "Pattern": "{ \"Metadata1\": [ rule1 ], \"data\": { \"Data1\": [ rule2 ] }}" } ] }

为了更清楚起见,以下是在纯 JSON 中展开的筛选条件 Pattern 的值。

{ "Metadata1": [ pattern1 ], "data": { "Data1": [ pattern2 ] } }

FilterCriteria 对象具有三个主要部分:元数据属性、数据属性和筛选条件模式。例如,假设您从事件源收到一个与以下类似的 Kinesis 事件:

"kinesis": { "partitionKey": "1", "sequenceNumber": "49590338271490256608559692538361571095921575989136588898", "data": { "City": "Seattle", "State": "WA", "Temperature": "46", "Month": "December" }, "approximateArrivalTimestamp": 1545084650.987 }
  • 元数据属性是指事件对象的字段。在示例 FilterCriteria 中,Metadata1 表示一个元数据属性。在 Kinesis 事件示例中,Metadata1 是指一个字段,例如 partitionKey

  • 数据属性是指事件主体的字段。在示例 FilterCriteria 中,Data1 表示一个数据属性。在 Kinesis 事件示例中,Data1 是指 CityTemperature 等字段。

    注意

    要对数据属性进行筛选,请确保将它们包含在属性键内的 FilterCriteria 中。此键取决于事件源。对于 Kinesis 事件源,数据键为 data。对于 Amazon SQS 事件源,数据键为 body。对于 DynamoDB 事件源,数据键为 dynamodb

  • 筛选条件规则用于定义想要应用到特定属性的筛选条件。在示例 FilterCriteria 中,rule1 将应用于 Metadata1rule2 将应用于 Data1。筛选条件规则的语法取决于您使用的比较运算符。有关更多信息,请参阅 筛选条件规则语法 筛选示例

在创建 FilterCriteria 对象时,仅指定您想要筛选条件与之匹配的元数据属性和数据属性。要使 Lambda 将事件视为匹配项,事件必须包含筛选条件中包含的所有字段名称。Lambda 将会忽略筛选条件中未包含的字段。

筛选条件规则语法

对于筛选条件规则,Lambda 支持与 Amazon EventBridge 相同的语法和规则集。有关更多信息,请参阅《Amazon EventBridge 用户指南》中的 Amazon EventBridge 事件模式

以下是可用于 Lambda 事件筛选的所有比较运算符的汇总。

比较运算符 示例 规则语法

Null

用户 ID 为空

"UserID": [ null ]

Empty

姓氏为空

"LastName": [""]

等于

名字为“Alice”

"Name": [ "Alice" ]

And

位置为“纽约”,日期为“星期一”

"Location": [ "New York" ], "Day": ["Monday"]

或者

付款类型为“信用卡”或“借记卡”

"PaymentType": [ "Credit", "Debit"]

天气是除“下雨”以外的任何天气

"Weather": [ { "anything-but": [ "Raining" ] } ]

数值(等于)

价格为 100

"Price": [ { "numeric": [ "=", 100 ] } ]

数值(范围)

价格大于 10,且小于等于 20

"Price": [ { "numeric": [ ">", 10, "<=", 20 ] } ]

Exists

产品名存在

"ProductName": [ { "exists": true } ]

不存在

产品名不存在

"ProductName": [ { "exists": false } ]

始于

地区位于美国

"Region": [ {"prefix": "us-" } ]

注意

与 EventBridge 一样,对于字符串,Lambda 使用精确的逐个字符匹配,而不进行小写化或任何其他字符串标准化。此外,对于数值,Lambda 使用字符串表示。例如,300、300.0 和 3.0e2 不相等。

筛选示例

假设您有一个 Kinesis 事件源,并且您希望函数只处理具有特定 partitionKey(元数据属性)的事件。此外,您只希望处理 Location 字段(数据属性)等于“Los Angeles”的事件。在这种情况下,您的 FilterCriteria 对象与以下类似:

{ "Filters": [ { "Pattern": "{ \"partitionKey\": [ \"1\" ], \"data\": { \"Location\": [ \"Los Angeles\" ] }}" } ] }

为了更清楚起见,以下是在纯 JSON 中展开的筛选条件 Pattern 的值。

{ "partitionKey": [ "1" ], "data": { "Location": [ "Los Angeles" ] } }

上一个示例为 partitionKeyLocation 使用了等于比较运算符。

在另一个示例中,假设您想要只处理 Temperature 数据属性大于 50,但小于等于 60 的事件。在这种情况下,您的 FilterCriteria 对象与以下类似:

{ "Filters": [ { "Pattern": "{ \"data\": { \"Temperature\": [ {\"numeric\": [ \">\", 50, \"<=\", 60 ] }]}" } ] }

为了更清楚起见,以下是在纯 JSON 中展开的筛选条件 Pattern 的值。

{ "data": { "Temperature": [ {"numeric": [ ">", 50, "<=", 60 ] } ] } }

上一个示例为 Temperature 使用了数值(范围)用于比较运算符。

多层筛选

您还可以使用事件筛选来处理多层 JSON 筛选。例如,假设您收到一个 DynamoDB 流事件,其中包含与以下类似的数据对象:

"dynamodb": { "Keys": { "Id": { "N": "101" } }, "NewImage": { "Message": { "S": "New item!" }, "Id": { "N": "101" } }, "SequenceNumber": "111", "SizeBytes": 26, "StreamViewType": "NEW_AND_OLD_IMAGES" }

假设您只想处理键 ID 值 N 为 101 的事件。在这种情况下,您的 FilterCriteria 对象与以下类似:

{ "Filters": [ { "Pattern": "{ \"dynamodb\": { \"Keys\": { \"Id\": { \"N\": [ "101" ] } } } }" } ] }

为了更清楚起见,以下是在纯 JSON 中展开的筛选条件 Pattern 的值。

{ "dynamodb": { "Keys": { "Id": { "N": [ "101" ] } } } }

上一个示例为 N 使用了等于比较运算符,它是嵌套在 dynamodb 数据字段中的多个层。

将筛选条件附加到事件源映射(控制台)

按照以下步骤使用 Lambda 控制台创建包含筛选条件的新事件源映射。

使用筛选条件创建新事件源映射(控制台)

  1. 打开 Lamba 控制台的 Functions(函数)页面

  2. 选择要为其创建事件源映射的函数名称。

  3. Function overview (函数概览) 下,选择 Add trigger (添加触发器)

  4. 对于 Trigger configuration(触发器配置),请选择支持事件筛选的触发器类型。这些类型包括 SQSDynamoDBKinesis

  5. 展开 Additional settings(其他设置)。

  6. Filter criteria(筛选条件)下,定义并输入筛选条件。例如,您可以输入以下筛选条件:

    { "a" : [ 1, 2 ] }

    这指示 Lambda 只处理字段 a 等于 1 或 2 的记录。

  7. 选择 Add (添加)

使用控制台输入筛选条件时,您只需提供筛选条件模式。在上述说明的第 6 步中,{ "a" : [ 1, 2 ] } 对应于下面的 FilterCriteria

{ "Filters": [ { "Pattern": "{ \"a\" : [ 1, 2 ] }" } ] }

在控制台中创建事件源映射后,您可以在触发器详细信息中看到格式化后的 FilterCriteria。请注意,在使用控制台输入筛选条件时,您无需提供 Pattern 键或转义引号。

注意

预设情况下,每个事件源可以有五个不同的筛选条件。您可以请求提高配额,以便将每个事件源的筛选条件提高至最多 10 个。Lambda 控制台允许您添加最多 10 个筛选条件,具体取决于账户的当前配额。如果您尝试添加的筛选条件数量超过当前配额允许的数量,则在您尝试创建事件源时,Lambda 将会引发错误。

将筛选条件附加到事件源映射(Amazon CLI)

假设您希望事件源映射具有以下 FilterCriteria

{ "Filters": [ { "Pattern": "{ \"a\" : [ 1, 2 ] }" } ] }

要使用 Amazon Command Line Interface(Amazon CLI)创建包含这些筛选条件的新事件源映射,请运行以下命令:

aws lambda create-event-source-mapping \ --function-name my-function \ --event-source-arn arn:aws:sqs:us-east-2:123456789012:my-queue \ --filter-criteria "{\"Filters\": [{\"Pattern\": \"{ \"a\" : [ 1, 2 ]}\"}]}"

CreateEventSourceMapping 命令将为包含指定 FilterCriteria 的函数 my-function 创建新的 Amazon SQS 事件源映射。

要将这些筛选条件添加到现有事件源映射中,请运行以下命令:

aws lambda update-event-source-mapping \ --uuid "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \ --filter-criteria "{\"Filters\": [{\"Pattern\": \"{ \"a\" : [ 1, 2 ]}\"}]}"

请注意,要更新事件源映射,您需要其 UUID。您可以通过 ListEventSourceMappings 调用获取 UUID。此外,Lambda 还会在CreateEventSourceMapping API 响应中返回 UUID。

要从事件源中删除筛选条件,您可以运行以下包含空 FilterCriteria 对象的 UpdateEventSourceMapping 命令:

aws lambda update-event-source-mapping \ --uuid "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \ --filter-criteria "{}"

正确筛选 Amazon SQS 消息

如果 Amazon SQS 消息不符合您的筛选条件,Lambda 会自动从队列中删除该消息。您无需在 Amazon SQS 中手动删除这些消息。

对于 Amazon SQS,消息 body 可以是任何字符串。但如果您的 FilterCriteria 期望 body 为有效的 JSON 格式,则可能会导致问题。反之亦然 — 如果传入的消息 body 为有效的 JSON 格式,则在您的筛选条件期望 body 为纯字符串时,这可能会导致出现意外行为。

要避免此问题,请确保 FilterCriteriabody 的格式与您从队列中收到的消息中的 body 的期望格式一致。在筛选消息之前,Lambda 会自动评估传入消息 body 的格式以及 body 的筛选条件模式的格式。如果不一致,Lambda 将会删除此消息。下表汇总了此评估:

传入消息 body 格式 筛选条件模式 body 格式 导致的操作

纯字符串

纯字符串

Lambda 根据您的筛选条件进行筛选。

纯字符串

数据属性中没有筛选条件模式

Lambda 根据您的筛选条件进行筛选(仅限其他元数据属性)。

纯字符串

有效 JSON

Lambda 将会丢弃消息。

有效 JSON

纯字符串

Lambda 将会丢弃消息。

有效 JSON

数据属性中没有筛选条件模式

Lambda 根据您的筛选条件进行筛选(仅限其他元数据属性)。

有效 JSON

有效 JSON

Lambda 根据您的筛选条件进行筛选。

如果您的 FilterCriteria 不包括 body,则 Lambda 将会跳过此检查。

正确筛选 Kinesis 和 DynamoDB 消息

在筛选条件处理了 Kinesis 或 DynamoDB 记录后,流迭代器会跳过此记录。如果记录不符合筛选条件,您无需从事件源手动删除记录。保留期结束后,Kinesis 和 DynamoDB 会自动删除这些旧记录。如果您希望提前删除记录,请参阅更改数据保留期

要正确筛选流事件源中的事件,数据字段和数据字段的筛选条件都必须为有效的 JSON 格式。(对于 Kinesis,数据字段为 data。对于 DynamoDB,数据字段为 dynamodb。) 如果任一字段不为有效的 JSON 格式,Lambda 将会丢弃消息或引发异常。下表汇总了具体行为:

传入数据格式(datadynamodb 数据属性中的筛选条件模式格式 导致的操作

有效 JSON

有效 JSON

Lambda 根据您的筛选条件进行筛选。

有效 JSON

数据属性中没有筛选条件模式

Lambda 根据您的筛选条件进行筛选(仅限其他元数据属性)。

有效 JSON

非 JSON

Lambda 在事件源映射创建或更新时引发异常。数据属性的筛选条件模式必须为有效的 JSON 格式。

非 JSON

有效 JSON

Lambda 将丢弃记录。

非 JSON

数据属性中没有筛选条件模式

Lambda 根据您的筛选条件进行筛选(仅限其他元数据属性)。

非 JSON

非 JSON

Lambda 在事件源映射创建或更新时引发异常。数据属性的筛选条件模式必须为有效的 JSON 格式。