

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

# 使用表达式
<a name="ddb-mapper-expressions"></a>

****  
**DynamoDB Mapper 是开发者预览版。它功能不完整，可能会发生变化。**

某些 DynamoDB 操作[接受](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.html)可用于指定约束或条件的表达式。DynamoDB Mapper 提供了一种惯用的 Kotlin DSL 来创建表达式。DSL 为您的代码带来了更好的结构和可读性，还可以更轻松地编写表达式。

本节介绍了 DSL 语法并提供了各种示例。

## 在操作中使用表达式
<a name="ddb-mapper-expressions-basic-usage"></a>

你可以在诸如这样的操作中使用表达式`scan`，它们会根据你定义的条件筛选返回的项目。要在 DynamoDB Mapper 中使用表达式，请在操作请求中添加表达式组件。

以下片段显示了在`scan`操作中使用的筛选表达式的示例。它使用 lambda 参数来描述筛选条件，该条件将要返回的项目限制为`year`属性值为 2001 的项目：

```
val table = // A table instance.

table.scanPaginated {
    filter {
        attr("year") eq 2001
    }
}
```

以下示例显示了在两个地方支持表达式的`query`操作：排序键筛选和非键过滤：

```
table.queryPaginated {
    keyCondition = KeyFilter(partitionKey = 1000) { sortKey startsWith "M" }
    filter {
        attr("year") eq 2001
    }
}
```

前面的代码将结果筛选为满足所有三个条件的结果：
+ 分区键属性值为 1000 *-AND-*
+ 排序键属性值以字母 *M* *-* AND-开头
+ 年份属性值为 2001

## DSL 组件
<a name="ddb-mapper-expressions-dsl"></a>

DSL 语法公开了几种用于构建表达式的组件（如下所述）。

### 属性
<a name="ddb-mapper-expressions-dsl-attrs"></a>

大多数条件都引用属性，这些属性由其密钥或文档路径标识。使用 DSK，您可以使用`attr`函数创建所有属性引用，也可以进行其他修改。

以下代码显示了一系列从简单到复杂的示例属性引用，例如按索引进行列表取消引用和按键进行映射取消引用：

```
attr("foo")           // Refers to the value of top-level attribute `foo`.

attr("foo")[3]        // Refers to the value at index 3 in the list value of
                      // attribute `foo`.

attr("foo")[3]["bar"] // Refers to the value of key `bar` in the map value at
                      // index 3 of the list value of attribute `foo`.
```

### 平等与不平等
<a name="ddb-mapper-expressions-dsl-eq-and-ineq"></a>

可以按等式和不等式比较表达式中的属性值。您可以将属性值与文字值或其他属性值进行比较。用于指定条件的函数有：
+ `eq`: 等于（等于`==`）
+ `neq`: 不等于（等于`!=`）
+ `gt`: 大于（等于`>`）
+ `gte`: 大于或等于（等于`>=`）
+ `lt`: 小于（等于`<`）
+ `lte`: 小于或等于（等于`<=`）

您可以使用中缀表示法将比较函数与参数组合在一起，如以下示例所示：

```
attr("foo") eq 42           // Uses a literal. Specifies that the attribute value `foo` must be
                            // equal to 42.

attr("bar") gte attr("baz") // Uses another attribute value. Specifies that the attribute 
                            // value `bar` must be greater than or equal to the
                            // attribute value of `baz`.
```

### 范围和套装
<a name="ddb-mapper-expressions-dsl-ranges-sets"></a>

除了单个值外，您还可以将属性值与范围或集合中的多个值进行比较。您可以使用中缀`[isIn](https://docs.aws.amazon.com/sdk-for-kotlin/api/latest/dynamodb-mapper/aws.sdk.kotlin.hll.dynamodbmapper.expressions/-filter/is-in.html)`函数进行比较，如以下示例所示：

```
attr("foo") isIn 0..99  // Specifies that the attribute value `foo` must be
                        // in the range of `0` to `99` (inclusive).

attr("foo") isIn setOf( // Specifies that the attribute value `foo` must be
    "apple",            // one of `apple`, `banana`, or `cherry`.
    "banana",
    "cherry",
)
```

该`isIn`函数为集合（例如`Set<String>`）和可以表示为 Kotlin 的边界`[ClosedRange<T>](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.ranges/-closed-range/)`（例如）提供重载。`[IntRange](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.ranges/-int-range/)`对于无法表示为 a 的边界`ClosedRange<T>`（例如字节数组或其他属性引用），可以使用以下`[isBetween](https://docs.aws.amazon.com/sdk-for-kotlin/api/latest/dynamodb-mapper/aws.sdk.kotlin.hll.dynamodbmapper.expressions/-filter/is-between.html)`函数：

```
val lowerBytes = byteArrayOf(0x48, 0x65, 0x6c)  // Specifies that the attribute value
val upperBytes = byteArrayOf(0x6c, 0x6f, 0x21)  // `foo` is between the values
attr("foo").isBetween(lowerBytes, upperBytes)   // `0x48656c` and `0x6c6f21`

attr("foo").isBetween(attr("bar"), attr("baz")) // Specifies that the attribute value
                                                // `foo` is between the values of
                                                // attributes `bar` and `baz`.
```

### 布尔逻辑
<a name="ddb-mapper-expressions-dsl-boolean"></a>

您可以使用以下函数组合单个条件或使用布尔逻辑进行更改：
+ `and`: 每个条件都必须为真（等同于` &&`）
+ `or`: 至少有一个条件必须为真（等同于`||`）
+ `not`: 给定条件必须为假（等同于`!`）

以下示例显示了每个函数：

```
and(                           // Both conditions must be met:
    attr("foo") eq "banana",   // * attribute value `foo` must equal `banana`
    attr("bar") isIn 0..99,    // * attribute value `bar` must be between
)                              //   0 and 99 (inclusive)

or(                            // At least one condition must be met:
    attr("foo") eq "cherry",   // * attribute value `foo` must equal `cherry`
    attr("bar") isIn 100..199, // * attribute value `bar` must be between
)                              //   100 and 199 (inclusive)

not(                           // The attribute value `foo` must *not* be
    attr("baz") isIn setOf(    // one of `apple`, `banana`, or `cherry`.
        "apple",               // Stated another way, the attribute value
        "banana",              // must be *anything except* `apple`, `banana`,
        "cherry",              // or `cherry`--including potentially a
    ),                         // non-string value or no value at all.
)
```

您可以通过布尔函数进一步组合布尔条件来创建嵌套逻辑，如以下表达式所示：

```
or(
    and(
        attr("foo") eq 123,
        attr("bar") eq "abc",
    ),
    and(
        attr("foo") eq 234,
        attr("bar") eq "bcd",
    ),
)
```

前面的表达式将结果筛选为满足以下任一条件的结果：
+  这两个条件都成立：
  + `foo`属性值为 123 *-AND-*
  + `bar`属性值为 “abc” 
+ 这两个条件都成立：
  + `foo`属性值为 234 *-AND-*
  + `bar`属性值为 “bcd” 

这等同于以下 Kotlin 布尔表达式：

```
(foo == 123 && bar == "abc") || (foo == 234 && bar == "bcd")
```

### 函数和属性
<a name="ddb-mapper-expressions-dsl-functions"></a>

以下函数和属性提供了额外的表达式功能：
+ `[contains](https://docs.aws.amazon.com/sdk-for-kotlin/api/latest/dynamodb-mapper/aws.sdk.kotlin.hll.dynamodbmapper.expressions/-filter/contains.html)`: 检查 string/list 属性值是否包含给定值
+ `[exists](https://docs.aws.amazon.com/sdk-for-kotlin/api/latest/dynamodb-mapper/aws.sdk.kotlin.hll.dynamodbmapper.expressions/-filter/exists.html)`: 检查属性是否已定义并包含任何值（包括`null`）
+ `[notExists](https://docs.aws.amazon.com/sdk-for-kotlin/api/latest/dynamodb-mapper/aws.sdk.kotlin.hll.dynamodbmapper.expressions/-filter/not-exists.html)`: 检查属性是否未定义
+ `[isOfType](https://docs.aws.amazon.com/sdk-for-kotlin/api/latest/dynamodb-mapper/aws.sdk.kotlin.hll.dynamodbmapper.expressions/-filter/is-of-type.html)`: 检查属性值是否为给定类型，例如字符串、数字、布尔值等
+ `[size](https://docs.aws.amazon.com/sdk-for-kotlin/api/latest/dynamodb-mapper/aws.sdk.kotlin.hll.dynamodbmapper.expressions/-filter/size.html)`: 获取属性的大小，例如集合中元素的数量或字符串的长度
+ `[startsWith](https://docs.aws.amazon.com/sdk-for-kotlin/api/latest/dynamodb-mapper/aws.sdk.kotlin.hll.dynamodbmapper.expressions/-filter/starts-with.html)`: 检查字符串属性值是否以给定的子字符串开头

以下示例说明了可以在表达式中使用的其他函数和属性的用法：

```
attr("foo") contains "apple" // Specifies that the attribute value `foo` must be
                             // a list that contains an `apple` element or a string
                             // which contains the substring `apple`.

attr("bar").exists()         // Specifies that the `bar` must exist and have a
                             // value (including potentially `null`).

attr("baz").size lt 100      // Specifies that the attribute value `baz` must have
                             // a size of less than 100.

attr("qux") isOfType AttributeType.String // Specifies that the attribute `qux`
                                          // must have a string value.
```

### 对关键筛选器进行排序
<a name="ddb-mapper-expressions-dsl-sort-key"></a>

排序键上的筛选表达式（例如在`query`操作的`keyCondition`参数中）不使用命名的属性值。要在筛选器中使用排序键，必须在所有比较`sortKey`中使用该关键字。`sortKey`关键字将替换`attr("<sort key name>")`，如以下示例所示：

```
sortKey startsWith "abc" // The sort key attribute value must begin with the
                         // substring `abc`.

sortKey isIn 0..99       // The sort key attribute value must be between 0
                         // and 99 (inclusive).
```

不能将排序键过滤器与布尔逻辑结合使用，它们仅支持上述比较的子集：
+ [等式和不等式](#ddb-mapper-expressions-dsl-eq-and-ineq)：支持所有比较
+ [范围和集合](#ddb-mapper-expressions-dsl-ranges-sets)：支持所有比较
+ [布尔逻辑](#ddb-mapper-expressions-dsl-boolean)：不支持
+ [函数和属性](#ddb-mapper-expressions-dsl-functions)：`startsWith`仅支持