我的数据库中有以下项目:
我的 pk 是 userId:string ,我的排序键是 teamId#taskId#checkpointId
我的 BE(节点)上的端点如下所示:
router.get("/user/:userId/:teamId/:taskId", async (req, res) => {
const { userId, taskId, teamId } = req.params;
const { success, data } = await getUserById(userId, teamId, taskId);
if (success) {
return res.json({ success, data });
}
return res.status(500).json({ success: false, message: "Error" });
});
我的处理程序看起来像这样:
const getUserById = async (userId, teamId, taskId) => {
const params = {
TableName: Table,
KeyConditionExpression:
"userId = :userId AND begins_with(teamId#taskId#checkpointId, :teamTaskId)",
ExpressionAttributeValues: {
":userId": userId,
":teamTaskId": `${teamId}#${taskId}#`,
},
ScanIndexForward: true, // Sort by taskDate in ascending order
};
try {
const { Items = [] } = await db.query(params).promise();
return { success: true, data: Items };
} catch (error) {
return { success: false, data: null };
}
};
我仔细检查以确保参数没有未定义,我的要求是:
localhost:8000/api/user/123456/987/321
我想获得所有检查点,因为我有一些检查点,因此是 begin_with,但由于某种原因,我没有得到成功的响应。
问题
您没有获得成功的响应,因为您在 KeyConditionExpression 中使用了特殊字符。
这就是您目前拥有的:
KeyConditionExpression:
"userId = :userId AND begins_with(teamId#taskId#checkpointId, :teamTaskId)"
但是,dynamo 在 KeyConditionExpression 中以不同方式对待
#
字符。 #
字符表示将被 ExpressionAttributeName 替换的标记的开始。这与 dynamo 如何用 ExpressionAttributeValues 替换任何用 :
字符表示的内容非常相似。
在您的情况下,您希望 dynamo 将
teamId#taskId#checkpointId
视为单个属性名称,但由于 #
字符,这种情况不会发生,dynamo 会尝试替换 #taskId 和 #checkpointId 的值,两者都会失败。
解决方案:
当您的 KeyConditionExpression 的属性名称中包含 #(或此处官方保留字列表中指定的任何其他字符)等特殊字符时,您应该使用 ExpressionAttributeNames 查询选项 为此类属性名称提供别名。例如,在您的情况下,查询将如下所示:
const getUserById = async (userId, teamId, taskId) => {
const params = {
TableName: Table,
KeyConditionExpression:
"userId = :userId AND begins_with(#SK, :teamTaskId)",
ExpressionAttributeValues: {
":userId": userId,
":teamTaskId": `${teamId}#${taskId}#`,
},
ExpressionAttributeNames: {
"#SK": "teamId#taskId#checkpointId",
},
ScanIndexForward: true, // Sort by taskDate in ascending order
};
// ...other existing code
};
SK 是我选择代表排序键属性的任意术语,它可以是您选择的任何其他字符串。
进行此更改后,您应该会收到成功的响应。