簡體   English   中英

Amazon DyanamoDB,在 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: Invalid FilterExpression: 未定義表達式中使用的表達式屬性值; 屬性值::val(服務:AmazonDynamoDBv2;狀態代碼:400;錯誤代碼:ValidationException;請求 ID:FEQBP55SPJIT60JVFPVO6N6BLBVV4KQNSO5AEMVJF66Q9ASUAAJG)

您正在濫用 API。 查看Map<String, Object> expressionAttributeValues

  1. :val:val1在那里。
  2. 您沒有將其傳遞給new ScanRequest()

這是 DynamoDB API V2 的 Java 示例。 假設我們有一個名為 Work 的表和一個名為 Archive 的列。 存檔列可以關閉或打開。

在此處輸入圖片說明

現在假設,我們只想查詢打開的項目。 使用 Java v2 和 Enhanced Client,我們可以按如下方式執行此查詢。

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]
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM