我试图根据两个不同列的组合将表格中的项目保持唯一。
我有一个instanceId和imageId列(以及其他内容),基于Stackoverflow和AWS Forums上的几个帖子,下面应该有效吗?
public void saveUnique(Server server) {
DynamoDBSaveExpression saveExpression = new DynamoDBSaveExpression();
Map<String, ExpectedAttributeValue> expectedAttributes =
ImmutableMap.<String, ExpectedAttributeValue>builder()
.put("instanceId", new ExpectedAttributeValue(false))
.put("imageId", new ExpectedAttributeValue(false))
.build();
saveExpression.setExpected(expectedAttributes);
saveExpression.setConditionalOperator(ConditionalOperator.AND);
try {
mapper.save(server, saveExpression);
} catch (ConditionalCheckFailedException e) {
//Handle conditional check
}
}
但是每次我尝试保存重复的项目(相同的instanceId和imageId)时,它都会成功保存到数据库中。
我在这里错过了什么?
编辑R.E notionquest回答
更新到下面的答案。
我有一个每分钟运行一次API的工作。 API的响应表示为Server
POJO。 Server
有一个名为instanceId
的属性。
我想确保如果Server
instanceId
已经在数据库中,请不要保存。
Server
对象具有id
的另一个属性,该属性被设置为表主键。
public void saveUnique(Server server) {
DynamoDBSaveExpression saveExpression = new DynamoDBSaveExpression();
Map<String, ExpectedAttributeValue> expected = new HashMap<>();
expected.put("instanceId", new ExpectedAttributeValue(new AttributeValue(server.getInstanceId())).withComparisonOperator(ComparisonOperator.NE));
saveExpression.setExpected(expected);
try {
mapper.save(server, saveExpression);
} catch (ConditionalCheckFailedException e) {
LOGGER.info("Skipped saving as not unique...");
}
}
此代码将反复保存Server对象,但不会抛出异常。
服务器POJO
@DynamoDBTable(tableName = "Servers")
public class Server {
@Id
private String id = UUID.randomUUID().toString();
@DynamoDBTypeConvertedJson
private Task task;
@DynamoDBAttribute(attributeName = "instanceId")
private String instanceId;
public Server() {
}
@DynamoDBHashKey
public String getId() {
return id;
}
// other standard getters and setters
}
答案 0 :(得分:4)
如果我正确理解了这个问题,那么您希望确保不是哈希键的字段的唯一性。
(我不确定为什么你不使用instanceId
作为Servers表的哈希键,我想你有理由这样做。)
我的回答:看起来像如果不使用辅助表就不能这样做。
这是您现有的Servers表:
+----------------------------------------------+
| Servers |
+----------------------------------------------+
| * id the hash key |
| * instanceId non-key field, must be unique|
| |
| * ... |
| * other fields |
| * ... |
+----------------------------------------------+
我会创建一个使用instanceId作为哈希键的附加表:
+----------------------------------------------+
| Instance |
+----------------------------------------------+
| * instanceId the hash key |
+----------------------------------------------+
拥有这样的表,在将记录保存到服务器之前,您必须这样做
首先通过向Instance添加记录(putItem)来确保instanceId值是唯一的,提供类似attribute_not_exists(instanceId)
的ConditionExpression。
仅当put操作完成而没有ConditionalCheckFailedException
错误时,您才可以继续将记录添加到Servers中。
如果您想基于两个字段instanceId和imageId的组合来确保服务器中记录的唯一性, 而不是只是instanceId使用这些字段的连接值作为aux表中的单个字段:
+----------------------------------------------+
| Instance_Image |
+----------------------------------------------+
| * instanceId_imageId the hash key |
+----------------------------------------------+
答案 1 :(得分:0)
以下代码检查属性值不等于是否为&#34;某些值&#34;如果条件满足,则更新项目。
Map<String, ExpectedAttributeValue> expected = new HashMap<>();
expected.put("yourattribute", new ExpectedAttributeValue(new AttributeValue("yourvalue")).withComparisonOperator(ComparisonOperator.NE));