Как изменить элемент во встроенном списке в dynamodb с клиентом документа
У меня есть таблица DynamoDB, где каждый элемент в таблице имеет массив комментариев в качестве атрибута. Моя схема выглядит примерно так:
{
"id": "abc",
"name": "This is an item"
"comments": [
"commentId": "abcdefg",
"commentAuthor": "Alice",
"commentDetails": "This item is my favourite!"
]
}
Я хочу, чтобы иметь возможность редактировать отдельный комментарий по его commentId
, но не ясно, как написать выражение DynamoDB для этого обновления (я использую DocumentClient).
Как мы можем обновить запись во встроенном массиве в Dynamo? Можно ли обновить индексом массива или выражением запроса?
Ответы
Ответ 1
Я думаю, что в вашей модели данных должна быть какая-то модификация. Вы должны были использовать карту dynamodb для этого, просто сделайте свой комментарий в качестве ключа для доступа к каждому комментарию
{
"id": "abc",
"name": "This is an item"
"comments": {
"abcdefg":{
"commentAuthor": "Alice",
"commentDetails": "This item is my favourite!"
}
}
}
Тогда запрос будет выглядеть так, и вы должны знать две вещи, чтобы обновить комментарий. 1 - Идентификатор элемента и 2 - идентификатор комментария.
var params = {
TableName: Tablename,
Key: {id: "abc"},
UpdateExpression:"set comments.#abcdefg.commentDetails=:val1",
ExpressionAttributeNames: {
"#abcdefg":"abcdefg"
},
ExpressionAttributeValues:{
":val1":"New comment text"
}
}
db.update(param,callback);
Пожалуйста, дайте мне знать и простите меня, объясните свой вопрос, если я неправильно понял, поскольку у меня не было достаточного количества баллов, чтобы убрать мои сомнения в комментарии.
Ответ 2
Лично я бы не стал помещать элементы, которые я хочу редактировать или часто обращаться к далекому от первичного ключа. Помните, что DynamoDB - это, в основном, хранилище ключей, поэтому всякий раз, когда вы хотите получить доступ к материалам, всегда лучше иметь эти предметы, открытые через первичные ключи.
Итак, что вы можете сделать по этому поводу, на мой взгляд, лучший способ - слегка изменить вашу модель данных. Поэтому я бы создал таблицу с идентификатором первичного ключа и ключом сортировки типа элемента. В вашем случае у вас теперь будут два типа элементов: "Item" и "comment_ [commentID]". В каждом комментарии могут быть поля автора и детали в качестве атрибутов, что-то вроде этого:
- [ID - ITEMTYPE] - NAME
- "abc" - "item" - "This is an item"
- [ID - ITEMTYPE] - AUTHOR - DETAILS
- "abc" - "comment_abcdefg" - "Alice" - "This item is my favourite!"
Теперь, если вы хотите получить все комментарии к элементу, который вы просто запрашиваете для идентификатора элемента, ключ сортировки начинается с "комментария". Если вы хотите отредактировать комментарий, вы можете просто получить этот элемент, добавив идентификатор в ключ сортировки, который приведет к точному совпадению. (также это было бы очень быстро). Существует несколько способов сделать это еще более гибким, но этого должно быть достаточно, чтобы делать то, о чем вы просили.
Извините, я просто прочитал ваш комментарий к другому ответу, конечно, вы можете добавить сортировочный номер между комментарием и полем идентификатора в типе сортировки типа элемента таким образом, чтобы комментарии сортировались автоматически в этом порядке (или отменили курс),
Ответ 3
Можно ли обновить по индексу массива...?
Да, это довольно легко, если вы знаете индекс. Это сработало для меня в локальном локальном localhost:8000/shell/
сейчас. Я предположил, что каждый элемент comments
списке comments
является объектом и что вы забыли скобки {}
вокруг атрибутов комментария в вашем примере. Пожалуйста, дайте мне знать, если я неправильно понял или если вам больше нужно.
var params = {
TableName: 'table_name',
Key: { // The primary key of the item (a map of attribute name to AttributeValue)
id: 'abc', //(string | number | boolean | null | Binary)
// more attributes...
},
UpdateExpression: 'SET comments[1] = :value', // String representation of the update to an attribute
// SET set-action , ...
// REMOVE remove-action , ... (for document support)
// ADD add-action , ...
// DELETE delete-action , ... (previous DELETE equivalent)
ExpressionAttributeValues: { // a map of substitutions for all attribute values
':value': {
commentId: 'abcdefg1',
commentAuthor: 'Alice',
commentDetails: 'changed'
}
},
ReturnValues: 'NONE', // optional (NONE | ALL_OLD | UPDATED_OLD | ALL_NEW | UPDATED_NEW)
ReturnConsumedCapacity: 'NONE', // optional (NONE | TOTAL | INDEXES)
ReturnItemCollectionMetrics: 'NONE', // optional (NONE | SIZE)
};
docClient.update(params, function(err, data) {
if (err) ppJson(err); // an error occurred
else ppJson(data); // successful response
});
Выход: