Как правильно использовать list_append, чтобы сохранить уникальные значения в DynamoDB? - PullRequest
0 голосов
/ 11 декабря 2018

В следующем коде контакты добавляются в атрибут контактов, даже если они уже существуют в нем.Но я хотел бы предотвратить дублирование, потому что не имеет смысла иметь один и тот же контакт дважды.Я пытался использовать содержимое безуспешно.У вас есть идеи, как мне это сделать?

const contact = event.contactId
const params = {
    TableName,
    Key: {
        userId: event.userId
    },
    ReturnValues: 'UPDATED_NEW',
    UpdateExpression: 'set #contacts = list_append((if_not_exists(#contacts, :empty_list), :contact)',
    ExpressionAttributeNames: {
        '#contacts': 'contacts'
    },
    ExpressionAttributeValues: {
        ':contact': [contact],
        ':empty_list': []
    }
} // TODO: Must be unique IDs

dynamodb.update(params, (err, data) => {
    if (err) {
        console.log(err)
        callback(err)
    } else {
        console.log(data)
        const response = {
            statusCode: 200,
            message: "Successfully added contact " + contact,
            updatedContacts: data.Attributes.contacts
        }
        callback(null, response)
    }
})

1 Ответ

0 голосов
/ 11 декабря 2018

Насколько мне известно, вам нужно использовать Set вместо List идентификаторов контактов, чтобы достичь желаемого только в одном вызове DynamoDB .При этом есть два способа сделать это с помощью Set, и это можно сделать с помощью списка, если у вас все в порядке, прочитав, прежде чем сохранить новый контакт.

Опция 1

DynamoDB поддерживает использование ADD для атрибутов набора, а набор гарантирует отсутствие дублирующих идентификаторов.Вы можете использовать ADD, чтобы молча преуспеть, не вызывая дубликат контакта, используя этот метод.

Если вы используете ADD, ваше выражение обновления будет

ADD #contacts :contact

Этот метод будет работать независимо от того, являются ли ваши контактные идентификаторы числом или строкой.

Опция 2

Используйте выражение условия , чтобы предотвратить добавление контакта, если он уже присутствует.DynamoDB имеет функцию contains(path, operand), которая поддерживает атрибуты String и StringSet.

Вы будете использовать то же выражение обновления, что и в варианте 1, и выражение условия для этого будет

attribute_not_exists(#contacts) OR NOT contains(#contacts, :contact)

Эта опция позволит вам узнать, что контакт уже присутствует, потому что есликонтакт уже присутствует, вы получите ответ ConditionalCheckFailed от DynamoDB.

Опция 3

Начните с чтения текущих List контактов из DynamoDB.В своем заявлении убедитесь, что вы не будете добавлять дубликаты.Если новый контакт будет дубликатом, вам больше нечего делать.Если контакт будет дубликатом, вы можете сохранить обновленный список контактов, используя эти выражения

UpdateExpression: “SET #contacts = :updatedContacts”
ConditionExpression: "#contacts = :oldContacts”

. В этом случае :oldContacts должен быть списком, который вы первоначально прочитали из DynamoDB.

Недостаток этого подхода заключается в том, что одновременное обновление списка может привести к сбою действительного обновления.

Вариант 4

Это наиболее сложный из всех подходов.Вы можете добавить атрибут version к элементам в таблице, и, как вариант 3, вы сначала читаете элемент, проверяете, что новый контакт не является дубликатом, а затем делаете условную запись.Однако в этом случае условная запись будет включать

UpdateExpression: “SET #contacts = :updatedContacts, #version = :newVersion”,
ConditionExpression: “#version = :oldVersion”

Это известно как Оптимистическая блокировка .Хотя это и не часть JavaScript SDK, в этом случае его достаточно просто реализовать самостоятельно.

Заключительные замечания

Вы должны знать, что опции 3 и 4 не будут работать для глобальной таблицы, которая одновременно обновляется в нескольких регионах.Вариант 2 может не сообщить вам о попытке добавить дубликат при тех же условиях, но он все равно будет гарантировать, что дубликатов не будет.( Глобальные таблицы в конечном итоге согласованы между регионами , поэтому выражение условия может иметь значение true для одного региона, но не для другого.)

Наконец, вы можете найти оператор сравнения и Справочник по функциям полезно, если вы хотите получить более подробную информацию о любой из функций, доступных для использования в условии или выражении обновления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...