Amazon DynamoDB,在 Java 中使用筛选表达式和扫描操作
Amazon DyanamoDB ,Using filter expressions with scan operations in Java
我正在尝试获取所有价格大于某个值的商品,但无法正确使用过滤器表达式。
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
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;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.PutItemRequest;
import com.amazonaws.services.dynamodbv2.model.ScanRequest;
import com.amazonaws.services.dynamodbv2.model.ScanResult;
public class QuerySample {
// Setting up the client
static AmazonDynamoDBClient db = new AmazonDynamoDBClient(
new ProfileCredentialsProvider());
// Setting up the DB
static DynamoDB dynamoDB = new DynamoDB(db);
public static void main(String a[]) {
// Setting up the Region
Region usWest = Region.getRegion(Regions.US_WEST_2);
db.setRegion(usWest);
Table table = dynamoDB.getTable("Thread");
SimpleDateFormat dt = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss.SSS");
long time = (new Date()).getTime();
Date date = new Date();
date.setTime(time);
System.out.println("The date is " + date);
// ScanRequest scanRequest = new ScanRequest()
// .withTableName("sys_ping");
// ScanResult result = db.scan(scanRequest);
// for (Map<String, AttributeValue> item : result.getItems()){
// System.out.println(item);
// }
Map<String, Object> expressionAttributeValues = new HashMap<String, Object>();
expressionAttributeValues.put(":val", "19");
expressionAttributeValues.put(":val1",
new AttributeValue().withN("2000"));
ScanRequest scanRequest = new ScanRequest().withTableName(
"ProductCatalog").withFilterExpression("Price >= :val");
ScanResult result = db.scan(scanRequest);
for (Map<String, AttributeValue> item : result.getItems()) {
System.out.println(item);
}
}
}
它抛出以下运行时异常
线程中的异常"main" com.amazonaws.AmazonServiceException:无效的FilterExpression:未定义表达式中使用的表达式属性值;属性值::val(服务:AmazonDynamoDBv2;状态代码:400;错误代码:ValidationException;请求 ID:FEQBP55SPJIT60JVFPVO6N6BLBVV4KQNSO5AEMVJF66Q9ASUAAJG)
您在滥用 API。看看Map<String, Object> expressionAttributeValues
- 那里既有
:val
又有:val1
。
- 您没有将其传递给
new ScanRequest()
这是 DynamoDB API V2 的 Java 示例。假设我们有一个名为 Work 的 table 和一个名为 Archive 的列。存档列可以关闭或打开。
现在假设,我们只想查询未清项。使用 Java v2 和增强客户端,我们可以按如下方式执行此查询。
package com.example.dynamodb;
// snippet-start:[dynamodb.java2.mapping.scanEx.import]
import java.time.Instant;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
import software.amazon.awssdk.enhanced.dynamodb.Expression;
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey;
import software.amazon.awssdk.enhanced.dynamodb.model.ScanEnhancedRequest;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
// snippet-end:[dynamodb.java2.mapping.scanEx.import]
/*
This code example uses an Expression object to select only Open items for the archive column.
Prior to running this code example, create a Work table that contains the following fields:
1. id - Represents the key.
2. date - Specifies the date the item was created.
3. description - A value that describes the item.
4. guide - A value that represents the deliverable being worked on.
5. status - A value that describes the status.
6. username - A value that represents the user who entered the item.
7. archive - A value that represents whether this is an active or archive item. Specify Open and Closed items.
*/
public class EnhancedScanRecordsWithExpression {
// Query the Record table
public static void main(String[] args) {
//Create a DynamoDbClient object
Region region = Region.US_EAST_1;
DynamoDbClient ddb = DynamoDbClient.builder()
.region(region)
.build();
// Create a DynamoDbEnhancedClient and use the DynamoDbClient object
DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
.dynamoDbClient(ddb)
.build();
scan(enhancedClient);
}
// snippet-start:[dynamodb.java2.mapping.scanEx.main]
public static void scan(DynamoDbEnhancedClient enhancedClient) {
try {
//Create a DynamoDbTable object
DynamoDbTable<Work> table = enhancedClient.table("Work", TableSchema.fromBean(Work.class));
AttributeValue attr = AttributeValue.builder()
.s("Open")
.build();
// Get only Open items in the Work table
Map<String, AttributeValue> myMap = new HashMap<>();
myMap.put(":val1", attr);
Map<String, String> myExMap = new HashMap<>();
myExMap.put("#archive", "archive");
// Set the Expression so only Closed items are queried from the Work table
Expression expression = Expression.builder()
.expressionValues(myMap)
.expressionNames(myExMap)
.expression("#archive = :val1")
.build();
ScanEnhancedRequest enhancedRequest = ScanEnhancedRequest.builder()
.filterExpression(expression)
.limit(15)
.build();
// Get items in the Record table and write out the ID value
Iterator<Work> results = table.scan().items().iterator();
while (results.hasNext()) {
Work rec = results.next();
System.out.println("The record id is " + rec.getId());
}
} catch (DynamoDbException e) {
System.err.println(e.getMessage());
System.exit(1);
}
System.out.println("Done");
}
// snippet-end:[dynamodb.java2.mapping.scanEx.main]
}
我正在尝试获取所有价格大于某个值的商品,但无法正确使用过滤器表达式。
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
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;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.PutItemRequest;
import com.amazonaws.services.dynamodbv2.model.ScanRequest;
import com.amazonaws.services.dynamodbv2.model.ScanResult;
public class QuerySample {
// Setting up the client
static AmazonDynamoDBClient db = new AmazonDynamoDBClient(
new ProfileCredentialsProvider());
// Setting up the DB
static DynamoDB dynamoDB = new DynamoDB(db);
public static void main(String a[]) {
// Setting up the Region
Region usWest = Region.getRegion(Regions.US_WEST_2);
db.setRegion(usWest);
Table table = dynamoDB.getTable("Thread");
SimpleDateFormat dt = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss.SSS");
long time = (new Date()).getTime();
Date date = new Date();
date.setTime(time);
System.out.println("The date is " + date);
// ScanRequest scanRequest = new ScanRequest()
// .withTableName("sys_ping");
// ScanResult result = db.scan(scanRequest);
// for (Map<String, AttributeValue> item : result.getItems()){
// System.out.println(item);
// }
Map<String, Object> expressionAttributeValues = new HashMap<String, Object>();
expressionAttributeValues.put(":val", "19");
expressionAttributeValues.put(":val1",
new AttributeValue().withN("2000"));
ScanRequest scanRequest = new ScanRequest().withTableName(
"ProductCatalog").withFilterExpression("Price >= :val");
ScanResult result = db.scan(scanRequest);
for (Map<String, AttributeValue> item : result.getItems()) {
System.out.println(item);
}
}
}
它抛出以下运行时异常
线程中的异常"main" com.amazonaws.AmazonServiceException:无效的FilterExpression:未定义表达式中使用的表达式属性值;属性值::val(服务:AmazonDynamoDBv2;状态代码:400;错误代码:ValidationException;请求 ID:FEQBP55SPJIT60JVFPVO6N6BLBVV4KQNSO5AEMVJF66Q9ASUAAJG)
您在滥用 API。看看Map<String, Object> expressionAttributeValues
- 那里既有
:val
又有:val1
。 - 您没有将其传递给
new ScanRequest()
这是 DynamoDB API V2 的 Java 示例。假设我们有一个名为 Work 的 table 和一个名为 Archive 的列。存档列可以关闭或打开。
现在假设,我们只想查询未清项。使用 Java v2 和增强客户端,我们可以按如下方式执行此查询。
package com.example.dynamodb;
// snippet-start:[dynamodb.java2.mapping.scanEx.import]
import java.time.Instant;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
import software.amazon.awssdk.enhanced.dynamodb.Expression;
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey;
import software.amazon.awssdk.enhanced.dynamodb.model.ScanEnhancedRequest;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
// snippet-end:[dynamodb.java2.mapping.scanEx.import]
/*
This code example uses an Expression object to select only Open items for the archive column.
Prior to running this code example, create a Work table that contains the following fields:
1. id - Represents the key.
2. date - Specifies the date the item was created.
3. description - A value that describes the item.
4. guide - A value that represents the deliverable being worked on.
5. status - A value that describes the status.
6. username - A value that represents the user who entered the item.
7. archive - A value that represents whether this is an active or archive item. Specify Open and Closed items.
*/
public class EnhancedScanRecordsWithExpression {
// Query the Record table
public static void main(String[] args) {
//Create a DynamoDbClient object
Region region = Region.US_EAST_1;
DynamoDbClient ddb = DynamoDbClient.builder()
.region(region)
.build();
// Create a DynamoDbEnhancedClient and use the DynamoDbClient object
DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
.dynamoDbClient(ddb)
.build();
scan(enhancedClient);
}
// snippet-start:[dynamodb.java2.mapping.scanEx.main]
public static void scan(DynamoDbEnhancedClient enhancedClient) {
try {
//Create a DynamoDbTable object
DynamoDbTable<Work> table = enhancedClient.table("Work", TableSchema.fromBean(Work.class));
AttributeValue attr = AttributeValue.builder()
.s("Open")
.build();
// Get only Open items in the Work table
Map<String, AttributeValue> myMap = new HashMap<>();
myMap.put(":val1", attr);
Map<String, String> myExMap = new HashMap<>();
myExMap.put("#archive", "archive");
// Set the Expression so only Closed items are queried from the Work table
Expression expression = Expression.builder()
.expressionValues(myMap)
.expressionNames(myExMap)
.expression("#archive = :val1")
.build();
ScanEnhancedRequest enhancedRequest = ScanEnhancedRequest.builder()
.filterExpression(expression)
.limit(15)
.build();
// Get items in the Record table and write out the ID value
Iterator<Work> results = table.scan().items().iterator();
while (results.hasNext()) {
Work rec = results.next();
System.out.println("The record id is " + rec.getId());
}
} catch (DynamoDbException e) {
System.err.println(e.getMessage());
System.exit(1);
}
System.out.println("Done");
}
// snippet-end:[dynamodb.java2.mapping.scanEx.main]
}