Насколько мне известно, вам нужно использовать 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 для одного региона, но не для другого.)
Наконец, вы можете найти оператор сравнения и Справочник по функциям полезно, если вы хотите получить более подробную информацию о любой из функций, доступных для использования в условии или выражении обновления.