DynamoDB 中的查询操作
Amazon DynamoDB 中的 Query
操作基于主键值查找项目。
您必须提供分区键属性的名称以及该属性的一个值。Query
将返回具有该分区键值的所有项目。(可选)您可以提供排序键属性,并使用比较运算符来细化搜索结果。
有关如何使用 Query
的更多信息,例如请求语法、响应参数和其他示例,请参阅《Amazon DynamoDB API 参考》中的查询。
查询的键条件表达式
要指定搜索条件,请使用键条件表达式—用于确定要从表或索引中读取的项目的字符串。
您必须指定分区键名称和值作为等式条件。无法在键条件表达式中使用非键属性。
您可选择为排序键提供另一个条件(如果有)。排序键条件必须使用下列比较运算符之一:
-
— 如果属性a
=b
a
等于值b
,则为 true -
— 如果a
<b
a
小于b
,则为 true -
— 如果a
<=b
a
小于等于b
,则为 true -
— 如果a
>b
a
大于b
,则为 true -
— 如果a
>=b
a
大于等于b
,则为 true -
— 如果a
BETWEENb
ANDc
a
大于或等于b
,且小于或等于c
,则为 true。
以下函数也受支持:
-
begins_with (
— 如果属性a
,substr
)
的值以特定子字符串开头,则为 true。a
以下 Amazon Command Line Interface (Amazon CLI) 示例将演示键条件表达式的用法。这些表达式使用占位符(例如 :name
和 :sub
)而不是实际的值。有关更多信息,请参阅DynamoDB 中的表达式属性名称和表达式属性值。
例
在 Thread
表中查询特定的 ForumName
(分区键)。具有 ForumName
值的所有项目将由查询进行读取,因为排序键 (Subject
) 未包括在 KeyConditionExpression
中。
aws dynamodb query \ --table-name Thread \ --key-condition-expression "ForumName = :name" \ --expression-attribute-values '{":name":{"S":"Amazon DynamoDB"}}'
例
在 Thread
表中查询特定的 ForumName
(分区键),但这一次仅返回具有给定 Subject
(排序键)的项目。
aws dynamodb query \ --table-name Thread \ --key-condition-expression "ForumName = :name and Subject = :sub" \ --expression-attribute-values file://values.json
--expression-attribute-values
的参数存储在文件 values.json
中。
{ ":name":{"S":"Amazon DynamoDB"}, ":sub":{"S":"DynamoDB Thread 1"} }
例
在 Reply
表中查询特定的 Id
(分区键),但仅返回其 ReplyDateTime
(排序键)以特定字符开头的项目。
aws dynamodb query \ --table-name Reply \ --key-condition-expression "Id = :id and begins_with(ReplyDateTime, :dt)" \ --expression-attribute-values file://values.json
--expression-attribute-values
的参数存储在文件 values.json
中。
{ ":id":{"S":"Amazon DynamoDB#DynamoDB Thread 1"}, ":dt":{"S":"2015-09"} }
您可以在键条件表达式中使用任意属性名称,前提是第一个字符是 a-z
或 A-Z
,其余字符(从第二个字符开始,如果存在)为 a-z
、A-Z
或 0-9
。此外,属性名称不得为 DynamoDB 保留字。(有关这些保留关键字的完整列表,请参阅DynamoDB 中的保留字。) 如果属性名称不满足这些要求,则您必须将表达式属性名称定义为占位符。有关更多信息,请参阅 DynamoDB 中的表达式属性名称。
对于具有给定分区键值的项目,DynamoDB 会将这些项目存储在紧邻位置并按照排序键值对其进行排序。在 Query
操作中,DynamoDB 按照排序顺序检索项目,然后使用 KeyConditionExpression
和可能存在的任何 FilterExpression
处理项目。只有在此时才会将 Query
结果发送回客户端。
Query
操作始终返回结果集。如果未找到匹配的项目,结果集将为空。
Query
结果始终按排序键值排序。如果排序键的数据类型为 Number
,则按照数值顺序返回结果。否则,按照 UTF-8 字节的顺序返回结果。默认情况下,系统按升序排序。要颠倒顺序,请将 ScanIndexForward
参数设置为 false
。
单个 Query
操作最多可检索 1 MB 的数据。在向结果应用任何 FilterExpression
或 ProjectionExpression
之前,将应用此限制。如果 LastEvaluatedKey
包含在响应中且为非 null 值,则您必须为结果集分页(请参阅对表查询结果分页)。
查询的筛选条件表达式
如果您需要进一步细化 Query
结果,则可以选择性地提供筛选表达式。筛选表达式可确定 Query
结果中应返回给您的项目。所有其他结果将会丢弃。
筛选表达式在 Query
已完成但结果尚未返回时应用。因此,无论是否存在筛选表达式,Query
都将占用同等数量的读取容量。
Query
操作最多可检索 1 MB 的数据。此限制在计算筛选表达式之前应用。
筛选表达式不得包含分区键或排序键属性。您需要在关键字条件表达式而不是筛选表达式中指定这些属性。
筛选表达式的语法与关键条件表达式的语法相似。筛选表达式可使用的比较运算符、函数和逻辑运算符与关键条件表达式可使用的相同。此外,筛选表达式可以使用不等于运算符 (<>
)、OR
运算符、CONTAINS
运算符、IN
运算符、BEGINS_WITH
运算符、BETWEEN
运算符、EXISTS
运算符和 SIZE
运算符。有关更多信息,请参阅 查询的键条件表达式 和 筛选条件和条件表达式的语法。
例
以下 Amazon CLI 示例在 Thread
表中查询特定 ForumName
(分区键)和 Subject
(排序键)。在找到的项目中,只返回最常用的讨论线程,换句话说,只有那些具有超过一定数量 Views
的线程。
aws dynamodb query \ --table-name Thread \ --key-condition-expression "ForumName = :fn and Subject = :sub" \ --filter-expression "#v >= :num" \ --expression-attribute-names '{"#v": "Views"}' \ --expression-attribute-values file://values.json
--expression-attribute-values
的参数存储在文件 values.json
中。
{ ":fn":{"S":"Amazon DynamoDB"}, ":sub":{"S":"DynamoDB Thread 1"}, ":num":{"N":"3"} }
请注意,Views
在 DynamoDB 中是一个保留字(请参阅 DynamoDB 中的保留字),因此本示例使用 #v
作为占位符。有关更多信息,请参阅 DynamoDB 中的表达式属性名称。
筛选表达式将从 Query
结果集中删除项目。在您预计会检索到大量项目并且还需要丢弃其中大多数项目的情况下,请尽量避免使用 Query
。
限制结果集中的项目数
Query
操作可让您限制它读取的项目数。为此,请将 Limit
参数设置为您需要的最大项目数。
例如,假设您对某个表进行 Query
,Limit
值为 6
,并且没有筛选表达式。Query
结果将包含表中与请求中的键条件表达式匹配的前 6 个项目。
现在假设您向 Query
添加了一个筛选表达式。在这种情况下,DynamoDB 最多可读取六个项目,然后仅返回与筛选表达式匹配的项目。最终 Query
结果包含六个或更少的项目,即使更多项目(如果 DynamoDB 继续读取更多项目)与过滤表达式匹配,也是如此。
对结果中的项目进行计数
除了与您的条件匹配的项目之外,Query
响应还包含以下元素:
-
ScannedCount
— 在应用筛选表达式(如果有)之前,与关键字条件表达式匹配的项目的数量。 -
Count
— 在应用筛选表达式(如果有)之后,剩余的项目的数量。
如果您不使用筛选表达式,那么 ScannedCount
和 Count
具有相同的值。
如果 Query
结果集的大小大于 1 MB,则 ScannedCount
和 Count
将仅表示项目总数的部分计数。您需要执行多次 Query
操作才能检索所有结果(请参阅对表查询结果分页)。
所有 Query
响应都将包含由该特定 Query
请求处理的项目的 ScannedCount
和 Count
。要获取所有 Query
请求的总和,您可以对 ScannedCount
和 Count
记录流水账。
查询占用的容量单位
您可对任何表或二级索引执行 Query
操作,前提是它具有复合主键(分区键和排序键)。Query
操作占用读取容量单位,如下所示。
如果对...进行 Query |
DynamoDB 将占用...的读取容量单位 |
---|---|
表 | 表的预置读取容量。 |
全局二级索引 | 索引的预置读取容量。 |
本地二级索引 | 基表的预置读取容量。 |
默认情况下,Query
操作不会返回任何有关它占用的读取容量大小的数据。但是,您可在 ReturnConsumedCapacity
请求中指定 Query
参数以获取此信息。下面是 ReturnConsumedCapacity
的有效设置:
-
NONE
— 不返回任何已占用容量数据。(这是默认值。) -
TOTAL
— 响应包含占用的读取容量单位的总数。 -
INDEXES
— 响应显示占用的读取容量单位的总数,以及访问的每个表和索引的占用容量。
DynamoDB 将基于项目大小而不是返回到应用程序的数据量来确定占用的读取容量单位数。因此,无论您是请求所有属性(默认行为)还是只请求部分属性(使用投影表达式),占用的容量单位数都是相同的。无论是否使用筛选表达式,该数量都是相同的。Query
对于为请求提供服务所涉及的每个分区均消耗一个最小读容量单位(对于最终一致性,原定设置为 0.5,对于强一致性,原定设置为 1.0),这包括不含任何项目的分区。
查询的读取一致性
默认情况下,Query
操作将执行最终一致性读取。这意味着 Query
结果可能无法反映由最近完成的 PutItem
或 UpdateItem
操作导致的更改。有关更多信息,请参阅 读取一致性。
如果您需要强一致性读取,请在 Query
请求中将 ConsistentRead
参数设置为 true
。