本文介绍了DynamoDBMapper仅在唯一时保存项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图根据两个不同列的组合将表格中的项目保持唯一。

I'm trying to keep items in my table unique based on a combination of two different columns.

我有一个instanceId和imageId列(以及其他列),并基于和以下内容应该有效吗?

I have an instanceId and imageId column (along with others) and based on a couple of posts on Stackoverflow and AWS Forums the below should work?

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)时,它都会成功保存到数据库中。

However every time I try and save a duplicate item (same instanceId and imageId) it's successfully being saved into the database.

我在这里错过了什么吗?

Am I missing anything else here?

编辑R.E notionquest回答

更新到下面的答案。

我有一个每分钟运行一次API的作业。 API的响应表示为服务器 POJO。 服务器具有名为 instanceId 的属性。

I have a job that runs once a minute polling an API. The response from the API is represented as a Server POJO. The Server has an attribute named instanceId.

我想确保如果服务器带有 instanceId 已经在数据库中,请不要保存。

I want to make sure that if a Server with that instanceId is already in the database, don't save it.

服务器对象具有另一个属性 id ,它被设置为表主键。

The Server object has another attribute of id which is set as the table primary key.

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对象除了永远不会抛出。

This code will save the Server object over and over again with the exception never being thrown.

服务器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
}


推荐答案

如果我正确理解了这个问题,你想确保一个不是哈希键的字段的唯一性。

If I correctly understood the question, you'd like to ensure uniqueness for a field which is not the hash key.

(我不确定为什么你不使用 instanceId 作为Servers表的哈希键,我想你有理由这样做。)

(I'm not sure why you do not use instanceId as the hash key for Servers table, I guess you have a reason for that).

我的答案:看起来像如果不使用辅助表就不能这样做。

My answer: looks like you can't do that without using an auxiliary table.

这是您现有的Servers表:

Here is your existing Servers table:

+----------------------------------------------+
|                 Servers                      |   
+----------------------------------------------+
| * id            the hash key                 |
| * instanceId    non-key field, must be unique|
|                                              |
| * ...                                        |
| * other fields                               |
| * ...                                        | 
+----------------------------------------------+

我会创建一个额外的表,其中instanceId作为哈希键:

I would create an additional table with instanceId as the hash key:

+----------------------------------------------+
|                 Instance                     |   
+----------------------------------------------+
| * instanceId    the hash key                 |
+----------------------------------------------+

拥有这样的表,在将记录保存到服务器之前,你需要
首先确保instanceId值是唯一的,方法是将一条记录(putItem)添加到Instance中,提供一个ConditionExpression,如 attribute_not_exists(instanceId)

Having such a table, before saving a record into Servers, you have to ensure first that instanceId value is unique by adding a record (putItem) into Instance, providing a ConditionExpression like attribute_not_exists(instanceId).

仅当put操作在没有 ConditionalCheckFailedException 错误的情况下完成时,您才可以继续将记录添加到Servers中。

And only if the put operation completes without an ConditionalCheckFailedException error, you can proceed with adding the record into Servers.

如果您想基于两个字段instanceId和imageId的组合确保服务器中记录的唯一性,则
而不仅仅是instanceId使用的连接值这些字段作为aux表中的单个字段:

If you'd like to ensure uniqueness of records in Servers based on combination of two fields, instanceId and imageId,instead of just instanceId use concatenated values of these fields as a single field in your aux table:

+----------------------------------------------+
|               Instance_Image                 |   
+----------------------------------------------+
| * instanceId_imageId   the hash key          |
+----------------------------------------------+

这篇关于DynamoDBMapper仅在唯一时保存项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-22 16:18