DynamoDB查询报错:Query condition missed key schema element: DocumentId
问题:DynamoDB查询报错“Query condition missed key schema element: DocumentId”
实体类 ImageDetail 代码
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.*; @DynamoDbBean public class ImageDetail { private String documentId; private String id; private int trackPosition; private String url; private String name; private double width; private double height; public ImageDetail() { // Default constructor is required for DynamoDBBean } public ImageDetail(String name) { this.name = name; } public ImageDetail(String name, String url, double width, double height) { this.name = name; this.url = url; this.width = width; this.height = height; } public ImageDetail(String name, double width, double height) { this.name = name; this.width = width; this.height = height; } public ImageDetail(String name, String url) { this.name = name; this.url = url; } @DynamoDbAttribute("Name") @DynamoDbIgnoreNulls public String getName() { return name; } public void setName(String name) { this.name = name; } @DynamoDbAttribute("Url") @DynamoDbIgnoreNulls public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } @DynamoDbAttribute("Width") @DynamoDbIgnoreNulls public double getWidth() { return width; } public void setWidth(double width) { this.width = width; } @DynamoDbAttribute("Height") @DynamoDbIgnoreNulls public double getHeight() { return height; } public void setHeight(double height) { this.height = height; } // Partition key @DynamoDbPartitionKey public String getDocumentId() { return documentId; } public void setDocumentId(String documentId) { this.documentId = documentId; } @DynamoDbAttribute("Id") @DynamoDbIgnoreNulls public String getId() { return id; } public void setId(String id) { this.id = id; } @DynamoDbSortKey @DynamoDbIgnoreNulls public int getTrackPosition() { return trackPosition; } public void setTrackPosition(int trackPosition) { this.trackPosition = trackPosition; } @Override public String toString() { return "ImageDetail{" + "documentId='" + documentId + '\'' + ", id='" + id + '\'' + ", trackPosition=" + trackPosition + ", url='" + url + '\'' + ", name='" + name + '\'' + ", width=" + width + ", height=" + height + '}'; } }
服务类 ImageService 代码
import com.amazonaws.services.lambda.runtime.LambdaLogger; import com.exiq.columbia.pdftools.model.image.ImageDetail; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import java.net.URI; import java.text.SimpleDateFormat; import java.util.TimeZone; import software.amazon.awssdk.enhanced.dynamodb.*; import software.amazon.awssdk.enhanced.dynamodb.model.*; import java.util.*; import java.util.UUID; public class ImageService { private DynamoDbClient client; private DynamoDbEnhancedClient enhancedClient; private DynamoDbTable<ImageDetail> imagesTable; private SimpleDateFormat sdf; public ImageService local() { client = DynamoDbClient.builder() .endpointOverride(URI.create("http://localhost:8000")) .region(Region.of(System.getenv("AWS_REGION"))) .build(); enhancedClient = DynamoDbEnhancedClient.builder() .dynamoDbClient(client) .build(); return this; } public ImageService cloud() { client = DynamoDbClient.builder() .region(Region.of(System.getenv("AWS_REGION"))) .build(); enhancedClient = DynamoDbEnhancedClient.builder() .dynamoDbClient(client) .build(); return this; } public ImageService init() { sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); sdf.setTimeZone(TimeZone.getTimeZone("UTC")); return this; } public ImageService withDefaultTable() { if (client == null) { cloud(); } imagesTable = enhancedClient.table(System.getenv("COLUMBIA_IMAGES_TABLE"), TableSchema.fromBean(ImageDetail.class)); return this; } public ImageService withImagesTable(String tableName) { this.imagesTable = enhancedClient.table(tableName, TableSchema.fromBean(ImageDetail.class)); return this; } public List<ImageDetail> getImagesByDocumentId(String documentId, LambdaLogger logger) { List<ImageDetail> imageDetails = new ArrayList<>(); try { // Query condition for the partition key only QueryConditional queryConditional = QueryConditional .keyEqualTo(k -> k.partitionValue(documentId)); logger.log("Querying for DocumentId: " + documentId); // Enhanced client operation to query the images Iterator<Page<ImageDetail>> results = imagesTable.query(r -> r.queryConditional(queryConditional)).iterator(); while (results.hasNext()) { Page<ImageDetail> page = results.next(); imageDetails.addAll(page.items()); } } catch (DynamoDbException e) { logger.log("Error retrieving images for documentId " + documentId + ": " + e.getMessage()); // Consider rethrowing the exception or handling it as necessary } return imageDetails; } public void saveOrUpdateImageRecords(String documentId, List<ImageDetail> imageDetails, LambdaLogger logger) { DynamoDbTable<ImageDetail> table = enhancedClient.table(System.getenv("COLUMBIA_IMAGES_TABLE"), TableSchema.fromBean(ImageDetail.class)); for (int i = 0; i < imageDetails.size(); i++) { ImageDetail imageDetail = imageDetails.get(i); // Set DocumentId and TrackPosition as they are your keys. logger.log("image detail " + i); logger.log(imageDetail.toString()); imageDetail.setDocumentId(documentId); imageDetail.setTrackPosition(i); imageDetail.setHeight(imageDetail.getHeight()); imageDetail.setWidth(imageDetail.getWidth()); imageDetail.setUrl(imageDetail.getUrl()); logger.log("Processing image: " + imageDetail.getName()); try { // Check if the record already exists ImageDetail itemToCheck = table.getItem(Key.builder() .partitionValue(documentId) .sortValue(i) .build()); if (itemToCheck != null) { // Update the existing record table.updateItem(imageDetail); } else { // Put a new item if it doesn't exist table.putItem(imageDetail); } logger.log("Operation succeeded for image: " + imageDetail.getName()); } catch (DynamoDbException e) { logger.log("Unable to process image: " + imageDetail.getName()); logger.log(e.getMessage()); // Handle the exception based on your use case } } } }
错误信息
Error retrieving images for documentId 2b820dad-4cf4-4a21-b243-8c0b840f56a2: Query condition missed key schema element: DocumentId (Service: DynamoDb, Status Code: 400, Request ID: B1MN9OTQVQ275DC8BGHTJVEFONVV4KQNSO5AEMVJF66Q9ASUAAJG)
解决建议
1. 修正实体类分区键的字段映射
你的实体类中,其他属性都通过@DynamoDbAttribute指定了表中的字段名(比如Name、Url),但分区键documentId只加了@DynamoDbPartitionKey注解,没有指定表字段名,导致增强客户端默认用小驼峰documentId作为查询的键名。而错误提示说明表的分区键实际是大驼峰DocumentId,两者不匹配。
修改getDocumentId()方法,添加@DynamoDbAttribute注解:
// Partition key @DynamoDbPartitionKey @DynamoDbAttribute("DocumentId") // 明确指定表中的分区键字段名 public String getDocumentId() { return documentId; }
2. 验证表结构一致性
确认DynamoDB表的键结构:
- 分区键:
DocumentId(字符串类型) - 排序键:
TrackPosition(数字类型)
确保和实体类的字段类型、名称完全匹配。
3. 统一表实例的使用
saveOrUpdateImageRecords方法中重新创建了DynamoDbTable实例,建议复用类中已初始化的imagesTable字段,避免重复初始化可能导致的配置不一致:
// 替换原方法中的table初始化代码 DynamoDbTable<ImageDetail> table = this.imagesTable;
4. 测试验证
修改后重新部署Lambda,调用getImagesByDocumentId方法测试,确认查询正常。
内容的提问来源于stack exchange,提问作者C96
相关产品推荐
相关产品推荐

