如何使用非主键的条件表达式将项目放入 DynamoDB
How to put the item in DynamoDB with conditional expression that is not Primary Key
生成随机 uuid
值后,我继续将其分配给 item.uuid
:
let uuid = uuidv4();
let title = "Title 100"
let item = {
uuid: uuid,
title: title
};
使用 Dynamodb table,其中主键是 item.uuid
属性,我将项目添加到 table 中:
let TABLE_NAME = "My Table Name";
let options = {};
let promise = dbClient.put_item({ Item: item, TableName: TABLE_NAME, ...options });
新项目被插入到 Dynamodb table 中,主键 uuid
之前生成。
接下来,我想添加另一个项目到同一个 table,具有相同的“title 101”标题:
let uuid = uuidv4();
let title = "title 101"
let item = {
uuid: uuid,
title: title
};
(两个项目将具有相同的 title
,但不同的 uuid
用作 table 中的主键)。
因为我想确定,只有当没有其他项目具有相同的“title 101”标题时才会添加此项目,我使用 ConditionExpression
:
let options = {
ConditionExpression: "#title <> :title",
ExpressionAttributeNames: {
"#title": "title"
},
ExpressionAttributeValues: {
":title" : "title 101"
}
}
let promise = dbClient.put_item({ Item: item, TableName: TABLE_NAME, ...options });
promise
.then(res => {
console.log('--------- SUCCESS --------');
console.log(res);
console.log('-----------------');
});
但无论此处使用的 ConditionExpression
是什么,DynamoDB 都会继续并添加具有相同 title
值的新项目。
有没有办法在不是主键的属性(字段)上使用条件表达式?
Condition Expressions
仅适用于update/delete(不适用于创建),即如果给定主键(PartitionKey + HashKey)的项目已经存在,则检查条件表达式的结果和如果 returns 为真,则继续。我们仍然需要传递整个主键。
我们可以尝试使用 scan + filter,但我们最终会读取整个 table 以找到与非键控属性匹配的行,这是高效的并且如果 table 很大。
因此,在这种情况下,最好的办法是在 title
和 运行 两个单独的查询上添加全局二级索引,首先按标题查询 GSI 以确定是否存在具有匹配标题和 put-item 如果不存在。
生成随机 uuid
值后,我继续将其分配给 item.uuid
:
let uuid = uuidv4();
let title = "Title 100"
let item = {
uuid: uuid,
title: title
};
使用 Dynamodb table,其中主键是 item.uuid
属性,我将项目添加到 table 中:
let TABLE_NAME = "My Table Name";
let options = {};
let promise = dbClient.put_item({ Item: item, TableName: TABLE_NAME, ...options });
新项目被插入到 Dynamodb table 中,主键 uuid
之前生成。
接下来,我想添加另一个项目到同一个 table,具有相同的“title 101”标题:
let uuid = uuidv4();
let title = "title 101"
let item = {
uuid: uuid,
title: title
};
(两个项目将具有相同的 title
,但不同的 uuid
用作 table 中的主键)。
因为我想确定,只有当没有其他项目具有相同的“title 101”标题时才会添加此项目,我使用 ConditionExpression
:
let options = {
ConditionExpression: "#title <> :title",
ExpressionAttributeNames: {
"#title": "title"
},
ExpressionAttributeValues: {
":title" : "title 101"
}
}
let promise = dbClient.put_item({ Item: item, TableName: TABLE_NAME, ...options });
promise
.then(res => {
console.log('--------- SUCCESS --------');
console.log(res);
console.log('-----------------');
});
但无论此处使用的 ConditionExpression
是什么,DynamoDB 都会继续并添加具有相同 title
值的新项目。
有没有办法在不是主键的属性(字段)上使用条件表达式?
Condition Expressions
仅适用于update/delete(不适用于创建),即如果给定主键(PartitionKey + HashKey)的项目已经存在,则检查条件表达式的结果和如果 returns 为真,则继续。我们仍然需要传递整个主键。
我们可以尝试使用 scan + filter,但我们最终会读取整个 table 以找到与非键控属性匹配的行,这是高效的并且如果 table 很大。
因此,在这种情况下,最好的办法是在 title
和 运行 两个单独的查询上添加全局二级索引,首先按标题查询 GSI 以确定是否存在具有匹配标题和 put-item 如果不存在。