Amazon DynamoDB
开发人员指南 (API Version 2012-08-10)
AWS 服务或AWS文档中描述的功能,可能因地区/位置而异。点 击 Getting Started with Amazon AWS to see specific differences applicable to the China (Beijing) Region.

步骤 4:查询和扫描数据

您可以使用 query 方法来检索表中的数据。您必须指定分区键值。排序键是可选项。

Movies 表的主键由以下部分组成:

  • year - 分区键。属性类型是数字。

  • title - 排序键。属性类型是字符串。

要查找一年当中发行的所有电影,您只需指定 year。您还可以提供 title 以根据某种条件 (作用于排序键) 来检索电影子集;例如,查找 2014 年发行并且标题以字母“A”开头的电影。

query 外,还可使用 scan 方法检索所有表数据。

要了解有关查询和扫描数据的更多信息,请分别参阅使用查询使用扫描

步骤 4.1:查询

此步骤中包含的代码将执行以下查询:

  • 检索所有在 1985 year 发行的电影。

  • 检索所有在 1992 year 发行并且 title 以字母“A”到字母“L”开头的电影。

  1. 将以下程序复制并粘贴到您的 Java 开发环境中:

    Copy
    // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.gsg; import java.util.HashMap; import java.util.Iterator; import com.amazonaws.client.builder.AwsClientBuilder; import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder; import com.amazonaws.services.dynamodbv2.document.DynamoDB; import com.amazonaws.services.dynamodbv2.document.Item; import com.amazonaws.services.dynamodbv2.document.ItemCollection; import com.amazonaws.services.dynamodbv2.document.QueryOutcome; import com.amazonaws.services.dynamodbv2.document.Table; import com.amazonaws.services.dynamodbv2.document.spec.QuerySpec; public class MoviesQuery { public static void main(String[] args) throws Exception { AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard() .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration("http://localhost:8000", "us-west-2")) .build(); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("Movies"); HashMap<String, String> nameMap = new HashMap<String, String>(); nameMap.put("#yr", "year"); HashMap<String, Object> valueMap = new HashMap<String, Object>(); valueMap.put(":yyyy", 1985); QuerySpec querySpec = new QuerySpec().withKeyConditionExpression("#yr = :yyyy").withNameMap(nameMap) .withValueMap(valueMap); ItemCollection<QueryOutcome> items = null; Iterator<Item> iterator = null; Item item = null; try { System.out.println("Movies from 1985"); items = table.query(querySpec); iterator = items.iterator(); while (iterator.hasNext()) { item = iterator.next(); System.out.println(item.getNumber("year") + ": " + item.getString("title")); } } catch (Exception e) { System.err.println("Unable to query movies from 1985"); System.err.println(e.getMessage()); } valueMap.put(":yyyy", 1992); valueMap.put(":letter1", "A"); valueMap.put(":letter2", "L"); querySpec.withProjectionExpression("#yr, title, info.genres, info.actors[0]") .withKeyConditionExpression("#yr = :yyyy and title between :letter1 and :letter2").withNameMap(nameMap) .withValueMap(valueMap); try { System.out.println("Movies from 1992 - titles A-L, with genres and lead actor"); items = table.query(querySpec); iterator = items.iterator(); while (iterator.hasNext()) { item = iterator.next(); System.out.println(item.getNumber("year") + ": " + item.getString("title") + " " + item.getMap("info")); } } catch (Exception e) { System.err.println("Unable to query movies from 1992:"); System.err.println(e.getMessage()); } } }

    注意

    • nameMap 提供名称替换功能。使用此参数是因为 year 是 DynamoDB 中的保留字,您不能直接在任何表达式中使用它,包括 KeyConditionExpression。您使用表达式属性名称 #yr 来解决此问题。

    • valueMap 提供值替换功能。使用此参数是因为您不能在任何表达式 (包括 KeyConditionExpression) 中使用文本。您使用表达式属性值 :yyyy 来解决此问题。

    首先,创建 querySpec 对象,用于描述查询参数,然后将此对象传递至 query 方法。

  2. 编译并运行程序。

注意

前面的程序演示了如何按主键属性对表进行查询。在 DynamoDB 中,您可以选择在表上创建一个或多个二级索引,并采用查询表的相同方法来查询这些索引。二级索引允许对非键属性进行查询,从而为您的应用程序带来额外的灵活性。有关更多信息,请参阅 使用二级索引改进数据访问

步骤 4.2:扫描

scan 方法将读取整个表中的所有项目,并返回表中的所有数据。您可提供一个可选的 filter_expression,以便仅返回符合条件的项目。但是,筛选条件仅在扫描整个表后应用。

以下程序将扫描整个 Movies 表,表中包含约 5000 个项目。扫描时可指定可选筛选条件,以便仅检索 20 世纪 50 年代以来的电影 (约 100 个项目),同时舍弃所有其他项目。

  1. 将以下程序复制并粘贴到您的 Java 开发环境中:

    Copy
    // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.gsg; import java.util.Iterator; import com.amazonaws.client.builder.AwsClientBuilder; import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder; import com.amazonaws.services.dynamodbv2.document.DynamoDB; import com.amazonaws.services.dynamodbv2.document.Item; import com.amazonaws.services.dynamodbv2.document.ItemCollection; import com.amazonaws.services.dynamodbv2.document.ScanOutcome; import com.amazonaws.services.dynamodbv2.document.Table; import com.amazonaws.services.dynamodbv2.document.spec.ScanSpec; import com.amazonaws.services.dynamodbv2.document.utils.NameMap; import com.amazonaws.services.dynamodbv2.document.utils.ValueMap; public class MoviesScan { public static void main(String[] args) throws Exception { AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard() .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration("http://localhost:8000", "us-west-2")) .build(); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("Movies"); ScanSpec scanSpec = new ScanSpec().withProjectionExpression("#yr, title, info.rating") .withFilterExpression("#yr between :start_yr and :end_yr").withNameMap(new NameMap().with("#yr", "year")) .withValueMap(new ValueMap().withNumber(":start_yr", 1950).withNumber(":end_yr", 1959)); try { ItemCollection<ScanOutcome> items = table.scan(scanSpec); Iterator<Item> iter = items.iterator(); while (iter.hasNext()) { Item item = iter.next(); System.out.println(item.toString()); } } catch (Exception e) { System.err.println("Unable to scan the table:"); System.err.println(e.getMessage()); } } }

    在代码中,请注意以下情况:

    • ProjectionExpression 用于指定要在扫描结果中包含的属性。

    • FilterExpression 用于指定一个条件,以便仅返回符合条件的项目。所有其他项目都将被舍弃。

  2. 编译并运行程序。

注意

您还可以对在表上创建的任意二级索引使用 Scan 操作。有关更多信息,请参阅 使用二级索引改进数据访问