【问题标题】:Amazon DyanamoDB ,Using filter expressions with scan operations in JavaAmazon DynamoDB,在 Java 中使用带有扫描操作的过滤器表达式
【发布时间】:2015-02-05 07:58:36
【问题描述】:

我正在尝试获取价格大于某个值的所有商品,但无法正确使用过滤器表达式。

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)

【问题讨论】:

    标签: amazon-dynamodb database-scan


    【解决方案1】:

    您在滥用 API。看Map&lt;String, Object&gt; expressionAttributeValues

    1. 那里有:val 和:val1。
    2. 您没有将其传递给new ScanRequest()

    【讨论】:

      【解决方案2】:

      这是 DynamoDB API V2 的 Java 示例。假设我们有一个名为 Work 的表和一个名为 Archive 的列。存档列可以关闭或打开。

      现在假设,我们只想查询 Open 项目。使用 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]
      }
      

      【讨论】:

      • 如果我们有多个列怎么办?我们可以链接表达式吗??
      猜你喜欢
      • 2019-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-05
      • 2012-12-09
      • 2021-05-25
      • 2020-08-29
      • 2022-11-06
      相关资源
      最近更新 更多