使用 DynamoDBMapper 的投影表达式

Nee*_*pta 5 amazon-web-services amazon-dynamodb

我有 500 个项目要使用 500 个主键属性检索,我想检索每个项目的 4 个属性而不是所有属性。我在 Java 中使用 DynamoDBMapper,但我无法找到将它们投影到特定数量的属性的方法。检索所有属性的成本可能非常高,因为其中一个属性可能非常大。有没有办法使用 DynamoDBMapper 获取所有这 500 个项目的 4 个属性?

mko*_*bit 4

是的,DynamoDBMapper支持将ProjectionExpressionsqueryscan方法一起使用。我在 上没有看到任何支持load

这是一个使用public <T> PaginatedQueryList<T> query(java.lang.Class<T> clazz, DynamoDBQueryExpression<T> queryExpression)并提供投影的示例DynamoDBQueryExpression。查看其中一个属性.withProjectionExpression("var1, #projectedVar")使用ExpressionAttributeNames的情况。如果您需要检索不是顶级属性的属性,则必须查看DocumentPaths 文档

import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBQueryExpression;
import com.amazonaws.services.dynamodbv2.datamodeling.PaginatedQueryList;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
import com.amazonaws.services.dynamodbv2.util.Tables;

import java.util.HashMap;
import java.util.Map;

public class MyTest {

    public static final String TABLE_NAME = "test_table";

    public static void main(String[] args) throws Exception {
        final AmazonDynamoDB dynamodb =
                new AmazonDynamoDBClient(new BasicAWSCredentials("aws", "key"));
        dynamodb.setEndpoint("http://localhost:8000");
        if (Tables.doesTableExist(dynamodb, TABLE_NAME)) {
            dynamodb.deleteTable(TABLE_NAME);
        }

        final DynamoDBMapper mapper = new DynamoDBMapper(dynamodb);
        final CreateTableRequest request = mapper.generateCreateTableRequest(MyClass.class)
                .withProvisionedThroughput(new ProvisionedThroughput(5L, 5L));

        dynamodb.createTable(request);

        final MyClass myClass1 = new MyClass();
        myClass1.setHash("H1");
        myClass1.setRange("R1");
        myClass1.setVar1("v1");
        myClass1.setVar2("v2");
        myClass1.setVar3("v3");
        mapper.save(myClass1);
        myClass1.setRange("R2");
        myClass1.setVar1("v4");
        myClass1.setVar2("v5");
        myClass1.setVar3("v6");
        mapper.save(myClass1);
        myClass1.setRange("R3");
        myClass1.setVar1("v7");
        myClass1.setVar2("v8");
        myClass1.setVar3("v9");
        mapper.save(myClass1);


        final HashMap<String, String> expressionAttributeNames = new HashMap<>();
        expressionAttributeNames.put("#myHash", "hash");
        expressionAttributeNames.put("#projectedVar", "var3");
        final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>();
        expressionAttributeValues.put(":hashValue", new AttributeValue("H1"));
        final DynamoDBQueryExpression<MyClass> queryExpression = new DynamoDBQueryExpression<MyClass>()
                .withKeyConditionExpression("#myHash = :hashValue")
                .withExpressionAttributeNames(expressionAttributeNames)
                .withExpressionAttributeValues(expressionAttributeValues)
                .withProjectionExpression("var1, #projectedVar");
        final DynamoDBMapperConfig mapperConfig =
                new DynamoDBMapperConfig(DynamoDBMapperConfig.ConsistentReads.CONSISTENT);
        final PaginatedQueryList<MyClass> query = mapper.query(MyClass.class, queryExpression, mapperConfig);

        query.forEach(System.out::println);
    }
}
Run Code Online (Sandbox Code Playgroud)
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBRangeKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;

@DynamoDBTable(tableName = MyTest.TABLE_NAME)
public class MyClass {
    private String hash;
    private String range;
    private String var1;
    private String var2;
    private String var3;

    @DynamoDBHashKey
    public String getHash() { return hash; }

    public void setHash(String hash) { this.hash = hash; }

    @DynamoDBRangeKey
    public String getRange() { return range; }

    public void setRange(String range) { this.range = range; }

    @DynamoDBAttribute
    public String getVar1() { return var1; }

    public void setVar1(String var1) { this.var1 = var1; }

    @DynamoDBAttribute
    public String getVar2() { return var2; }

    public void setVar2(String var2) { this.var2 = var2; }

    @DynamoDBAttribute
    public String getVar3() { return var3; }

    public void setVar3(String var3) { this.var3 = var3; }

    @Override
    public String toString() {
        return "MyClass{" +
                "hash='" + hash + '\'' +
                ", range='" + range + '\'' +
                ", var1='" + var1 + '\'' +
                ", var2='" + var2 + '\'' +
                ", var3='" + var3 + '\'' +
                '}';
    }
}
Run Code Online (Sandbox Code Playgroud)

输出显示仅检索投影属性:

import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBQueryExpression;
import com.amazonaws.services.dynamodbv2.datamodeling.PaginatedQueryList;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
import com.amazonaws.services.dynamodbv2.util.Tables;

import java.util.HashMap;
import java.util.Map;

public class MyTest {

    public static final String TABLE_NAME = "test_table";

    public static void main(String[] args) throws Exception {
        final AmazonDynamoDB dynamodb =
                new AmazonDynamoDBClient(new BasicAWSCredentials("aws", "key"));
        dynamodb.setEndpoint("http://localhost:8000");
        if (Tables.doesTableExist(dynamodb, TABLE_NAME)) {
            dynamodb.deleteTable(TABLE_NAME);
        }

        final DynamoDBMapper mapper = new DynamoDBMapper(dynamodb);
        final CreateTableRequest request = mapper.generateCreateTableRequest(MyClass.class)
                .withProvisionedThroughput(new ProvisionedThroughput(5L, 5L));

        dynamodb.createTable(request);

        final MyClass myClass1 = new MyClass();
        myClass1.setHash("H1");
        myClass1.setRange("R1");
        myClass1.setVar1("v1");
        myClass1.setVar2("v2");
        myClass1.setVar3("v3");
        mapper.save(myClass1);
        myClass1.setRange("R2");
        myClass1.setVar1("v4");
        myClass1.setVar2("v5");
        myClass1.setVar3("v6");
        mapper.save(myClass1);
        myClass1.setRange("R3");
        myClass1.setVar1("v7");
        myClass1.setVar2("v8");
        myClass1.setVar3("v9");
        mapper.save(myClass1);


        final HashMap<String, String> expressionAttributeNames = new HashMap<>();
        expressionAttributeNames.put("#myHash", "hash");
        expressionAttributeNames.put("#projectedVar", "var3");
        final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>();
        expressionAttributeValues.put(":hashValue", new AttributeValue("H1"));
        final DynamoDBQueryExpression<MyClass> queryExpression = new DynamoDBQueryExpression<MyClass>()
                .withKeyConditionExpression("#myHash = :hashValue")
                .withExpressionAttributeNames(expressionAttributeNames)
                .withExpressionAttributeValues(expressionAttributeValues)
                .withProjectionExpression("var1, #projectedVar");
        final DynamoDBMapperConfig mapperConfig =
                new DynamoDBMapperConfig(DynamoDBMapperConfig.ConsistentReads.CONSISTENT);
        final PaginatedQueryList<MyClass> query = mapper.query(MyClass.class, queryExpression, mapperConfig);

        query.forEach(System.out::println);
    }
}
Run Code Online (Sandbox Code Playgroud)