2015-10-05 2 views
2

У меня есть 500 элементов для извлечения, используя 500 атрибутов первичного ключа, и я хочу получить 4 атрибута каждого элемента вместо всех атрибутов. Я использую DynamoDBMapper в Java, но я не могу найти способ спроецировать их на определенное количество атрибутов. Извлечение всех атрибутов может быть очень дорогостоящим, поскольку один из атрибутов может быть очень большим. Есть ли способ получить 4 атрибута всех этих 500 элементов с помощью DynamoDBMapper?Выражение проекции с DynamoDBMapper

+0

Что вы подразумеваете под * «неспособным найти способ проецировать их на определенное количество атрибутов» *? Можете ли вы привести пример того, где вы столкнулись с проблемой? – mkobit

+0

Простой пример - предположим, что у меня есть таблица с (Studentid, student_name, lifetime_course_name_list) Я просто хочу ТОЛЬКО получить имена 500 студентов с учетом их идентификаторов. Предположим, что lifetime_course_name_list - это список курсов, которые студент взял за всю свою жизнь, так что это довольно просто. –

ответ

1

Да, DynamoDBMapper имеет поддержку для использования ProjectionExpressions с использованием методов query и scan. Я не вижу поддержки на load.

Вот пример использования public <T> PaginatedQueryList<T> query(java.lang.Class<T> clazz, DynamoDBQueryExpression<T> queryExpression) и обеспечения проекции DynamoDBQueryExpression. Посмотрите на .withProjectionExpression("var1, #projectedVar"), который использует ExpressionAttributeNames для одного атрибута. Если вам нужно получить атрибуты, которые не являются атрибутами верхнего уровня, вы должны смотреть на DocumentPaths documentation:

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); 
    } 
} 

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 + '\'' + 
       '}'; 
    } 
} 

И вывод, показывающий, что только предполагаемые атрибуты извлекаются:

MyClass{hash='null', range='null', var1='v1', var2='null', var3='v3'} 
MyClass{hash='null', range='null', var1='v4', var2='null', var3='v6'} 
MyClass{hash='null', range='null', var1='v7', var2='null', var3='v9'} 
+0

Согласно http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/JavaORMDynamoDBMapper.html «Вы можете запросить таблицу только в том случае, если ее первичный ключ выполнен как из хэша, так и из атрибута диапазона». Первичный ключ моей таблицы состоит только из хэша. Итак, я думаю, что «Query» для меня не вариант. Я что-то пропустил? –

+0

@NeerajGupta Знаете ли вы хэш-ключи предметов, которые хотите получить? – mkobit

Смежные вопросы