DynamoDB 开始_查询获取失败

问题描述 投票:0回答:1

我的数据库中有以下项目:

我的 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,但由于某种原因,我没有得到成功的响应。

node.js amazon-dynamodb
1个回答
0
投票

问题

您没有获得成功的响应,因为您在 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 是我选择代表排序键属性的任意术语,它可以是您选择的任何其他字符串。

进行此更改后,您应该会收到成功的响应。

© www.soinside.com 2019 - 2024. All rights reserved.