

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# AND/OR 逻辑
<a name="and-or-logic"></a>

使用筛选策略中的 AND/OR 逻辑来匹配 Amazon SNS 中的消息属性或消息正文属性。这可以实现更精确、更灵活的消息筛选。

## AND 逻辑
<a name="and-logic"></a>

您可使用多个属性名称来应用 AND 逻辑。

考虑以下策略：

```
{
  "customer_interests": ["rugby"],
  "price_usd": [{"numeric": [">", 100]}]
}
```

它匹配任何 `customer_interests` 值设置为 `rugby` *且* `price_usd` 值设置为大于 100 的数字的消息属性或消息正文属性。

**注意**  
您无法将 AND 逻辑应用于同一属性的值。

## OR 逻辑
<a name="or-logic"></a>

通过将多个值分配给一个属性名称来应用 OR 逻辑。

考虑以下策略：

```
{
   "customer_interests": ["rugby", "football", "baseball"]
}
```

它匹配任何 `customer_interests` 值设置为 `rugby`、`football`、*或* `baseball` 的消息属性或消息正文属性。

## OR 运算符
<a name="or-operator"></a>

您可以使用 `"$or"` 运算符明确定义筛选策略，以表达策略中多个属性之间的 OR 关系。

只有当策略满足以下所有条件时，Amazon SNS 才会识别 `"$or"` 关系。当其中任一条件未满足时，`"$or"` 会被视为常规属性名称，与策略中的任何其他字符串相同。
+ 规则中有一个 `"$or"` 字段属性，后跟一个数组，例如，`“$or” : []`。
+ `"$or"` 数组中至少有 2 个对象：`"$or": [{}, {}]`。
+ `"$or"` 数组中的所有对象都没有属于保留关键字的字段名。

否则，`"$or"` 将被视为普通属性名称，与策略中的其他字符串相同。

由于数字和前缀是保留关键字，因此以下策略不会被解析为 OR 关系。

```
{ 
   "$or": [ {"numeric" : 123}, {"prefix": "abc"} ] 
}
```

**`OR` 运算符示例**

标准 `OR`：

```
{
  "source": [ "aws.cloudwatch" ], 
  "$or": [
    { "metricName": [ "CPUUtilization" ] },
    { "namespace": [ "AWS/EC2" ] }
  ] 
}
```

此策略的筛选逻辑是：

```
"source" && ("metricName" || "namespace")
```

它匹配以下任一组消息属性：

```
"source": {"Type": "String", "Value": "aws.cloudwatch"},
"metricName": {"Type": "String", "Value": "CPUUtilization"}
```

或者

```
"source": {"Type": "String", "Value": "aws.cloudwatch"},
"namespace": {"Type": "String", "Value": "AWS/EC2"}
```

它还匹配以下任一消息正文：

```
{
    "source": "aws.cloudwatch",
    "metricName": "CPUUtilization"
}
```

或者

```
{
    "source": "aws.cloudwatch",
    "namespace": "AWS/EC2"
}
```

### 包括 `OR` 关系在内的策略限制
<a name="or-operator-constraints"></a>

考虑以下策略：

```
{
    "source": [ "aws.cloudwatch" ],
    "$or": [
      { "metricName": [ "CPUUtilization", "ReadLatency" ] },
      {
        "metricType": [ "MetricType" ] ,
        "$or" : [
          { "metricId": [ 1234, 4321 ] },
          { "spaceId": [ 1000, 2000, 3000 ] }
        ]
      }
    ]
  }
```

该策略的逻辑也可以简化为：

```
("source" AND "metricName") 
OR 
("source" AND "metricType" AND "metricId") 
OR 
("source" AND "metricType" AND "spaceId")
```

具有 OR 关系的策略的复杂度计算可以简化为每个 OR 语句的组合复杂度之和。

总组合数的计算方法如下所示：

```
(source * metricName) + (source * metricType * metricId) + (source * metricType * spaceId)
= (1 * 2) + (1 * 1 * 2) + (1 * 1 * 3) 
= 7
```

`source` 有一个值，`metricName` 有两个值，`metricType` 有一个值，`metricId` 有两个值，`spaceId` 有三个值。

考虑以下嵌套筛选策略：

```
{
    "$or": [
      { "metricName": [ "CPUUtilization", "ReadLatency" ] },
      { "namespace": [ "AWS/EC2", "AWS/ES" ] }
    ],
    "detail" : {
      "scope" : [ "Service" ],
      "$or": [
        { "source": [ "aws.cloudwatch" ] },
        { "type": [ "CloudWatch Alarm State Change"] }
      ]
    }
  }
```

该策略的逻辑可以简化为：

```
("metricName" AND ("detail"."scope" AND "detail"."source")
OR
("metricName" AND ("detail"."scope" AND "detail"."type")
OR
("namespace" AND ("detail"."scope" AND "detail"."source")
OR
("namespace" AND ("detail"."scope" AND "detail"."type")
```

组合总数的计算方法与非嵌套策略相同，只是我们需要考虑键的嵌套级别。

总组合数的计算方法如下所示：

```
(2 * 2 * 2) + (2 * 2 * 2) + (2 * 2 * 2) + (2 * 2 * 2) = 32
```

`metricName` 有两个值，`namespace` 有两个值，`scope` 是具有一个值的两级嵌套键，`source` 是具有一个值的两级嵌套键，`type` 是具有一个值的两级嵌套键。