了解事件网格订阅的事件筛选

本本介绍了筛选发送到终结点的事件的不同方法。 创建事件订阅时,有三个筛选选项:

  • 事件类型
  • 主题开头内容或结尾内容
  • 高级字段和运算符

Azure Resource Manager 模板

本文所示的示例是 JSON 代码片段,用于在 Azure 资源管理器 (ARM) 模板中定义筛选器。 有关完整 ARM 模板和部署 ARM 模板的示例,请参阅快速入门:使用 ARM 模板将 Blob 存储事件路由到 Web 终结点。 以下是与快速入门示例中的 filter 部分相关的其他部分。 ARM 模板定义以下资源。

  • Azure 存储帐户
  • 存储帐户的系统主题
  • 系统主题的事件订阅。 你将看到事件订阅部分的 filter 子部分。

在以下示例中,事件订阅筛选 Microsoft.Storage.BlobCreatedMicrosoft.Storage.BlobDeleted 事件。

{
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2021-08-01",
      "name": "[parameters('storageAccountName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "StorageV2",
      "properties": {
        "accessTier": "Hot"
      }
    },
    {
      "type": "Microsoft.EventGrid/systemTopics",
      "apiVersion": "2021-12-01",
      "name": "[parameters('systemTopicName')]",
      "location": "[parameters('location')]",
      "properties": {
        "source": "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]",
        "topicType": "Microsoft.Storage.StorageAccounts"
      },
      "dependsOn": [
        "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]"
      ]
    },
    {
      "type": "Microsoft.EventGrid/systemTopics/eventSubscriptions",
      "apiVersion": "2021-12-01",
      "name": "[format('{0}/{1}', parameters('systemTopicName'), parameters('eventSubName'))]",
      "properties": {
        "destination": {
          "properties": {
            "endpointUrl": "[parameters('endpoint')]"
          },
          "endpointType": "WebHook"
        },
        "filter": {
          "includedEventTypes": [
            "Microsoft.Storage.BlobCreated",
            "Microsoft.Storage.BlobDeleted"
          ]
        }
      },
      "dependsOn": [
        "[resourceId('Microsoft.EventGrid/systemTopics', parameters('systemTopicName'))]"
      ]
    }
  ]
}

事件类型筛选

默认情况下,事件源的所有事件类型都将发送到终结点。 可以决定仅将某些事件类型发送到终结点。 例如,可以收到有关资源更新的通知,但不会收到删除等其他操作的通知。 在这种情况下,按 Microsoft.Resources.ResourceWriteSuccess 事件类型进行筛选。 提供包含事件类型的数组或指定 All 以获取事件源的所有事件类型。

按事件类型筛选的 JSON 语法是:

"filter": {
  "includedEventTypes": [
    "Microsoft.Resources.ResourceWriteFailure",
    "Microsoft.Resources.ResourceWriteSuccess"
  ]
}

主题筛选

对于按主题的简单筛选,请指定主题的开头值或结尾值。 例如,可以使用 .txt 指定主题的结尾,以仅获取与将文本文件上传到存储帐户相关的事件。 或者,可以筛选以 /blobServices/default/containers/testcontainer 开头的主题以获取该容器的所有事件,但不获取存储帐户中的其他容器。

将事件发布到自定义主题时,可为事件创建主题,便于订阅者们了解他们是否对该事件感兴趣。 订阅者将使用主题属性来筛选和路由事件。 考虑添加事件发生位置的路径,以便订阅者可以按该路径的段进行筛选。 通过路径,订阅者可精确或宽泛地筛选事件。 如果在主题中提供一个由三个段构成的路径(如 /A/B/C),订阅者可根据第一个段 /A 进行筛选,获取范围较宽泛的一组事件。 这些订阅者会获取主题为 /A/B/C/A/D/E 这样的事件。 其他订阅者可通过 /A/B 进行筛选,这样可以获取范围更精确的一组事件。

示例(Blob 存储事件)

可以按事件类型、容器名称或已创建/删除的对象的名称来筛选 Blob 事件。

Blob 存储事件使用者使用的格式:

/blobServices/default/containers/<containername>/blobs/<blobname>

要匹配存储帐户的所有事件,可将主题筛选器留空。

要匹配在一组共享前缀的容器中创建的 blob 的事件,请使用 subjectBeginsWith 筛选器,如下所示:

/blobServices/default/containers/containerprefix

要匹配在特定容器中创建的 blob 的事件,请使用 subjectBeginsWith 筛选器,如下所示:

/blobServices/default/containers/containername/

要匹配在共享 blob 名称前缀的特定容器中创建的 blob 的事件,请使用 subjectBeginsWith 筛选器,如下所示:

/blobServices/default/containers/containername/blobs/blobprefix

若要匹配正在容器的特定子文件夹中创建的 Blob 的事件,请使用如下 subjectBeginsWith 筛选器:

/blobServices/default/containers/{containername}/blobs/{subfolder}/

要匹配在共享 blob 后缀的特定容器中创建的 blob 事件,请使用 subjectEndsWith 筛选器,例如“.log”或“.jpg”。

高级筛选

要按数据字段中的值进行筛选并指定比较运算符,请使用高级筛选选项。 在高级筛选中,指定:

  • 运算符类型 - 比较的类型。
  • 键 - 用于筛选的事件数据中的字段。 它可以是数字、布尔值、字符串或数组。
  • 值 - 要与键进行比较的值。

密钥

键是用于筛选的事件数据中的字段。 可以是下列类型之一:

  • Number

  • 布尔

  • 字符串

  • 数组。 需要将 enableAdvancedFilteringOnArrays 属性设置为 true 才能使用此功能。

    "filter":
    {
        "subjectBeginsWith": "/blobServices/default/containers/mycontainer/blobs/log",
        "subjectEndsWith": ".jpg",
        "enableAdvancedFilteringOnArrays": true
    }
    

对于云事件架构中的事件,请使用以下键值:eventidsourceeventtypeeventtypeversion 或事件数据(如 data.key1)。

如果使用的是事件网格基本层,则对于事件网格架构中的事件,请使用以下键值:IDTopicSubjectEventTypeDataVersion 或事件数据(如 data.key1)。 对于自定义输入架构,请使用事件数据字段(如 data.key1)。 若要访问数据节中的字段,请使用 .(点)表示法。 例如,使用 data.siteNamedata.appEventTypeDetail.action 访问以下示例事件的 siteNameaction

	"data": {
		"appEventTypeDetail": {
			"action": "Started"
		},
		"siteName": "<site-name>",
		"clientRequestId": "None",
		"correlationRequestId": "None",
		"requestId": "292f499d-04ee-4066-994d-c2df57b99198",
		"address": "None",
		"verb": "None"
	},

注意

事件网格不支持筛选对象数组。 它只允许相同类型的字符串、布尔值、数字和数组(如整数数组或字符串数​​组)。

值可以是:数字、字符串、布尔值或数组

运算符

可用的数字运算符为:

NumberIn

如果值为指定的筛选器值之一,则 NumberIn 运算符的计算结果为 true。 在以下示例中,它将检查 data 节中 counter 特性的值是 5 还是 1。

"advancedFilters": [{
    "operatorType": "NumberIn",
    "key": "data.counter",
    "values": [
        5,
        1
    ]
}]

如果键为数组,则会对照筛选器值的数组检查数组中的所有值。 下面是键为 [v1, v2, v3]、筛选器为 [a, b, c] 的伪代码。 任何数据类型与筛选器的数据类型不匹配的键值都会被忽略。

FOR_EACH filter IN (a, b, c)
    FOR_EACH key IN (v1, v2, v3)
        IF filter == key
            MATCH

NumberNotIn

如果不是任何指定的筛选器值,则 NumberNotIn 的计算结果为 true。 在以下示例中,它将检查 data 节中 counter 特性的值是否不是 41 和 0。

"advancedFilters": [{
    "operatorType": "NumberNotIn",
    "key": "data.counter",
    "values": [
        41,
        0
    ]
}]

如果键为数组,则会对照筛选器值的数组检查数组中的所有值。 下面是键为 [v1, v2, v3]、筛选器为 [a, b, c] 的伪代码。 任何数据类型与筛选器的数据类型不匹配的键值都会被忽略。

FOR_EACH filter IN (a, b, c)
    FOR_EACH key IN (v1, v2, v3)
        IF filter == key
            FAIL_MATCH

NumberLessThan

如果小于指定的筛选器值,则 NumberLessThan 运算符的计算结果为 true。 在以下示例中,它将检查 data 节中 counter 特性的值是否小于 100。

"advancedFilters": [{
    "operatorType": "NumberLessThan",
    "key": "data.counter",
    "value": 100
}]

如果键为数组,则会对照筛选器值检查数组中的所有值。 下面是键为 [v1, v2, v3] 的伪代码。 任何数据类型与筛选器的数据类型不匹配的键值都会被忽略。

FOR_EACH key IN (v1, v2, v3)
    IF key < filter
        MATCH

NumberGreaterThan

如果大于指定的筛选器值,则 NumberGreaterThan 运算符的计算结果为 true。 在以下示例中,它将检查 data 节中 counter 特性的值是否大于 20。

"advancedFilters": [{
    "operatorType": "NumberGreaterThan",
    "key": "data.counter",
    "value": 20
}]

如果键为数组,则会对照筛选器值检查数组中的所有值。 下面是键为 [v1, v2, v3] 的伪代码。 任何数据类型与筛选器的数据类型不匹配的键值都会被忽略。

FOR_EACH key IN (v1, v2, v3)
    IF key > filter
        MATCH

NumberLessThanOrEquals

如果小于或等于指定的筛选器值,则 NumberLessThanOrEquals 运算符的计算结果为 true。 在以下示例中,它将检查 data 节中 counter 特性的值是否小于或等于 100。

"advancedFilters": [{
    "operatorType": "NumberLessThanOrEquals",
    "key": "data.counter",
    "value": 100
}]

如果键为数组,则会对照筛选器值检查数组中的所有值。 下面是键为 [v1, v2, v3] 的伪代码。 任何数据类型与筛选器的数据类型不匹配的键值都会被忽略。

FOR_EACH key IN (v1, v2, v3)
    IF key <= filter
        MATCH

NumberGreaterThanOrEquals

如果大于或等于指定的筛选器值,则 NumberGreaterThanOrEquals 运算符的计算结果为 true。 在以下示例中,它将检查 data 节中 counter 特性的值是否大于或等于 30。

"advancedFilters": [{
    "operatorType": "NumberGreaterThanOrEquals",
    "key": "data.counter",
    "value": 30
}]

如果键为数组,则会对照筛选器值检查数组中的所有值。 下面是键为 [v1, v2, v3] 的伪代码。 任何数据类型与筛选器的数据类型不匹配的键值都会被忽略。

FOR_EACH key IN (v1, v2, v3)
    IF key >= filter
        MATCH

NumberInRange

如果值在指定的筛选器范围之一内,则 NumberInRange 运算符的计算结果为 true。 在以下示例中,它将检查 data 节中 key1 特性的值是否在以下两个范围之内:3.14159 - 999.95,3000 - 4000。

{
    "operatorType": "NumberInRange",
    "key": "data.key1",
    "values": [[3.14159, 999.95], [3000, 4000]]
}

values 属性是一个范围数组。 在以上示例中,它是两个范围的数组。 下面是具有一个要检查的范围的数组示例。

具有一个范围的数组:

{
    "operatorType": "NumberInRange",
    "key": "data.key1",
    "values": [[3000, 4000]]
}

如果键为数组,则会对照筛选器值的数组检查数组中的所有值。 下面是键为 [v1, v2, v3]、筛选器为范围数组的伪代码。 在此伪代码中,ab 为数组中每个范围的最低值和最高值。 任何数据类型与筛选器的数据类型不匹配的键值都会被忽略。

FOR_EACH (a,b) IN filter.Values
    FOR_EACH key IN (v1, v2, v3)
       IF key >= a AND key <= b
           MATCH

NumberNotInRange

如果不在任何指定的筛选器范围内,则 NumberNotInRange 运算符的计算结果为 true。 在以下示例中,它将检查 data 节中 key1 特性的值是否在以下两个范围之内:3.14159 - 999.95,3000 - 4000。 如果是,则运算符返回 false。

{
    "operatorType": "NumberNotInRange",
    "key": "data.key1",
    "values": [[3.14159, 999.95], [3000, 4000]]
}

values 属性是一个范围数组。 在以上示例中,它是两个范围的数组。 下面是具有一个要检查的范围的数组示例。

具有一个范围的数组:

{
    "operatorType": "NumberNotInRange",
    "key": "data.key1",
    "values": [[3000, 4000]]
}

如果键为数组,则会对照筛选器值的数组检查数组中的所有值。 下面是键为 [v1, v2, v3]、筛选器为范围数组的伪代码。 在此伪代码中,ab 为数组中每个范围的最低值和最高值。 任何数据类型与筛选器的数据类型不匹配的键值都会被忽略。

FOR_EACH (a,b) IN filter.Values
    FOR_EACH key IN (v1, v2, v3)
        IF key >= a AND key <= b
            FAIL_MATCH

可用的布尔值运算符为:

BoolEquals

如果值为指定的布尔值筛选器,则 BoolEquals 运算符的计算结果为 true。 在以下示例中,它将检查 data 节中 isEnabled 特性的值是否为 true

"advancedFilters": [{
    "operatorType": "BoolEquals",
    "key": "data.isEnabled",
    "value": true
}]

如果键为数组,则会对照筛选器布尔值检查数组中的所有值。 下面是键为 [v1, v2, v3] 的伪代码。 任何数据类型与筛选器的数据类型不匹配的键值都会被忽略。

FOR_EACH key IN (v1, v2, v3)
    IF filter == key
        MATCH

可用的字符串运算符为:

StringContains

如果包含任何指定的筛选器值(作为子字符串),则 StringContains 的计算结果为 true。 在以下示例中,它将检查 data 节中 key1 特性的值是否包含指定的子字符串之一:microsoftazure。 例如,azure data factory 中包含 azure

"advancedFilters": [{
    "operatorType": "StringContains",
    "key": "data.key1",
    "values": [
        "microsoft", 
        "azure"
    ]
}]

如果键为数组,则会对照筛选器值的数组检查数组中的所有值。 下面是键为 [v1, v2, v3]、筛选器为 [a,b,c] 的伪代码。 任何数据类型与筛选器的数据类型不匹配的键值都会被忽略。

FOR_EACH filter IN (a, b, c)
    FOR_EACH key IN (v1, v2, v3)
        IF key CONTAINS filter
            MATCH

StringNotContains

如果不包含指定的筛选器值作为子字符串,则 StringNotContains 运算符的计算结果为 true。 如果键包含一个指定值作为子字符串,则运算符的计算结果为 false。 在以下示例中,仅当 data 节中 key1 特性的值不包含 contosofabrikam 作为子字符串时,运算符才返回 true。

"advancedFilters": [{
    "operatorType": "StringNotContains",
    "key": "data.key1",
    "values": [
        "contoso", 
        "fabrikam"
    ]
}]

如果键为数组,则会对照筛选器值的数组检查数组中的所有值。 下面是键为 [v1, v2, v3]、筛选器为 [a,b,c] 的伪代码。 任何数据类型与筛选器的数据类型不匹配的键值都会被忽略。

FOR_EACH filter IN (a, b, c)
    FOR_EACH key IN (v1, v2, v3)
        IF key CONTAINS filter
            FAIL_MATCH

有关此运算符的当前限制,请参阅限制部分。

StringBeginsWith

如果值以任何指定的筛选器开头,则 StringBeginsWith 运算符的计算结果为 true。 在以下示例中,它将检查 data 节中 key1 特性的值是否以 eventmessage 开头。 例如,event hubsevent 开头。

"advancedFilters": [{
    "operatorType": "StringBeginsWith",
    "key": "data.key1",
    "values": [
        "event", 
        "message"
    ]
}]

如果键为数组,则会对照筛选器值的数组检查数组中的所有值。 下面是键为 [v1, v2, v3]、筛选器为 [a,b,c] 的伪代码。 任何数据类型与筛选器的数据类型不匹配的键值都会被忽略。

FOR_EACH filter IN (a, b, c)
    FOR_EACH key IN (v1, v2, v3)
        IF key BEGINS_WITH filter
            MATCH

StringNotBeginsWith

如果以任何指定的筛选器值开头,则 StringNotBeginsWith 运算符的计算结果为 true。 在以下示例中,它将检查 data 节中 key1 特性的值是否不以 eventmessage 开头。

"advancedFilters": [{
    "operatorType": "StringNotBeginsWith",
    "key": "data.key1",
    "values": [
        "event", 
        "message"
    ]
}]

如果键为数组,则会对照筛选器值的数组检查数组中的所有值。 下面是键为 [v1, v2, v3]、筛选器为 [a,b,c] 的伪代码。 任何数据类型与筛选器的数据类型不匹配的键值都会被忽略。

FOR_EACH filter IN (a, b, c)
    FOR_EACH key IN (v1, v2, v3)
        IF key BEGINS_WITH filter
            FAIL_MATCH

StringEndsWith

如果值以指定的筛选器值之一结尾,则 StringEndsWith 运算符的计算结果为 true。 在以下示例中,它将检查 data 节中 key1 特性的值是否以 jpgjpegpng 结尾。 例如,eventgrid.pngpng 结尾。

"advancedFilters": [{
    "operatorType": "StringEndsWith",
    "key": "data.key1",
    "values": [
        "jpg", 
        "jpeg", 
        "png"
    ]
}]

如果键为数组,则会对照筛选器值的数组检查数组中的所有值。 下面是键为 [v1, v2, v3]、筛选器为 [a,b,c] 的伪代码。 任何数据类型与筛选器的数据类型不匹配的键值都会被忽略。

FOR_EACH filter IN (a, b, c)
    FOR_EACH key IN (v1, v2, v3)
        IF key ENDS_WITH filter
            MATCH

StringNotEndsWith

如果以任何指定的筛选器值结尾,则 StringNotEndsWith 运算符的计算结果为 true。 在以下示例中,它将检查 data 节中 key1 特性的值是否不以 jpgjpegpng 结尾。

"advancedFilters": [{
    "operatorType": "StringNotEndsWith",
    "key": "data.key1",
    "values": [
        "jpg", 
        "jpeg", 
        "png"
    ]
}]

如果键为数组,则会对照筛选器值的数组检查数组中的所有值。 下面是键为 [v1, v2, v3]、筛选器为 [a,b,c] 的伪代码。 任何数据类型与筛选器的数据类型不匹配的键值都会被忽略。

FOR_EACH filter IN (a, b, c)
    FOR_EACH key IN (v1, v2, v3)
        IF key ENDS_WITH filter
            FAIL_MATCH

StringIn

StringIn 运算符检查值是否与指定的筛选器值之一完全匹配。 在以下示例中,它将检查 data 节中 key1 特性的值是否为 contosofabrikamfactory

"advancedFilters": [{
    "operatorType": "StringIn",
    "key": "data.key1",
    "values": [
        "contoso", 
        "fabrikam", 
        "factory"
    ]
}]

如果键为数组,则会对照筛选器值的数组检查数组中的所有值。 下面是键为 [v1, v2, v3]、筛选器为 [a,b,c] 的伪代码。 任何数据类型与筛选器的数据类型不匹配的键值都会被忽略。

FOR_EACH filter IN (a, b, c)
    FOR_EACH key IN (v1, v2, v3)
        IF filter == key
            MATCH

StringNotIn

StringNotIn 运算符检查值是否与任何指定的筛选器不匹配。 在以下示例中,它将检查 data 节中 key1 特性的值是否不是 awsbridge

"advancedFilters": [{
    "operatorType": "StringNotIn",
    "key": "data.key1",
    "values": [
        "aws", 
        "bridge"
    ]
}]

如果键为数组,则会对照筛选器值的数组检查数组中的所有值。 下面是键为 [v1, v2, v3]、筛选器为 [a,b,c] 的伪代码。 任何数据类型与筛选器的数据类型不匹配的键值都会被忽略。

FOR_EACH filter IN (a, b, c)
    FOR_EACH key IN (v1, v2, v3)
        IF filter == key
            FAIL_MATCH

所有字符串比较都不区分大小写。

注意

如果事件 JSON 不包含高级筛选键,则对于以下运算符,筛选器的计算结果为“不匹配”:NumberGreaterThan、NumberGreaterThanOrEquals、NumberLessThan、NumberLessThanOrEquals、NumberIn、BoolEquals、StringContains、StringNotContains、StringBeginsWith、StringNotBeginsWith、StringEndsWith、StringNotEndsWith、StringIn。

对于以下运算符,筛选器的计算结果为“匹配”:NumberNotIn、StringNotIn。

IsNullOrUndefined

如果键的值为 NULL 或未定义,则 IsNullOrUndefined 运算符的计算结果为 true。

{
    "operatorType": "IsNullOrUndefined",
    "key": "data.key1"
}

在以下示例中,缺少 key1,因此运算符的计算结果为 true。

{ 
    "data": 
    { 
        "key2": 5 
    } 
}

在以下示例中,key1 设置为 null,因此运算符的计算结果为 true。

{
    "data": 
    { 
        "key1": null
    }
}

如果 key1 在这些示例中具有其他任何值,则运算符将计算为 false。

IsNotNull

如果键的值不为 NULL 或未定义,则 IsNotNull 运算符的计算结果为 true。

{
    "operatorType": "IsNotNull",
    "key": "data.key1"
}

OR 和 AND

如果指定具有多个值的单个筛选器,则将执行 OR 操作,因此键字段的值必须是这些值之一。 下面是一个示例:

"advancedFilters": [
    {
        "operatorType": "StringContains",
        "key": "Subject",
        "values": [
            "/providers/microsoft.devtestlab/",
            "/providers/Microsoft.Compute/virtualMachines/"
        ]
    }
]

如果指定多个不同的筛选器,则将执行 AND 操作,因此必须满足每个筛选器条件。 下面是一个示例:

"advancedFilters": [
    {
        "operatorType": "StringContains",
        "key": "Subject",
        "values": [
            "/providers/microsoft.devtestlab/"
        ]
    },
    {
        "operatorType": "StringContains",
        "key": "Subject",
        "values": [
            "/providers/Microsoft.Compute/virtualMachines/"
        ]
    }
]

CloudEvents

对于 CloudEvents 架构中的事件,请使用以下键值:eventidsourceeventtypeeventtypeversion 或事件数据(如 data.key1)。

还可以使用 CloudEvents 1.0 中的扩展上下文特性。 在以下示例中,comexampleextension1comexampleothervalue 是扩展上下文特性。

{
    "specversion" : "1.0",
    "type" : "com.example.someevent",
    "source" : "/mycontext",
    "id" : "C234-1234-1234",
    "time" : "2018-04-05T17:31:00Z",
    "subject": null,
    "comexampleextension1" : "value",
    "comexampleothervalue" : 5,
    "datacontenttype" : "application/json",
    "data" : {
        "appinfoA" : "abc",
        "appinfoB" : 123,
        "appinfoC" : true
    }
}

下面是在筛选器中使用扩展上下文特性的示例。

"advancedFilters": [{
    "operatorType": "StringBeginsWith",
    "key": "comexampleothervalue",
    "values": [
        "5", 
        "1"
    ]
}]

限制

高级筛选具有以下限制:

  • 每个事件网格订阅的所有筛选器都有 25 个高级筛选器和 25 个筛选器值
  • 每个字符串值有 512 个字符
  • 具有 .(点)字符的键。 例如: http://schemas.microsoft.com/claims/authnclassreferencejohn.doe@contoso.com 。 目前不支持键中使用转义字符。

可以在多个筛选器中使用相同的键。

后续步骤