创建或更新 dynamodb

ron*_*ara 7 amazon-web-services node.js amazon-dynamodb aws-lambda

目前,我正在通过查询检查该项目是否存在,然后我正在使用 put 或 updateItem,我想更改它并对 DDB 进行一次调用。我想进行一个将更新或创建项目的查询。

这是我的项目的一个例子:

{
   id: 'dsfadsf'
   fa: { "apple" : { "S" : "76-100" }, "yolo" : { "S" : "0-25" }
   pa: { "finish" : { "BOOL" : false },    "userKey" : { "S" : "3e299e12-9e66" }  }
   createdAt: 32432432423
}
Run Code Online (Sandbox Code Playgroud)

物品类型:

createdAt - Number
fa - Map
pa - Map
id - String
finish - Boolean
key - String
Run Code Online (Sandbox Code Playgroud)

如果项目存在,我想推送一个新项目,如 {papa: 'dsfadsf'}(永远不要修改 fa Map 内的现有项目)并修改 pa Map 内的完成值

这是更新后的项目:

{
   id: 'dsfadsf'
   fa: { "apple" : { "S" : "76-100" }, "yolo" : { "S" : "0-25" }, "papa": { "S" : "dsfadsf"} }
   pa: { "finish" : { "BOOL" : true },    "userKey" : { "S" : "3e299e12-9e66" }  }
   createdAt: 32432432423
}
Run Code Online (Sandbox Code Playgroud)

这是我尝试过的,但它不起作用

{
    TableName: tableName,
    Key: {
      id: "dsfadsf",
    },
    UpdateExpression: `SET #id = :id, fa.${itemName} = if_not_exists(fa.${itemName}, :text), pa.finish = if_not_exists(pa.finish, :finishval), #ca = :ca`,
    ExpressionAttributeNames: {
      "#id": "id",
      "#ca": createdAt
    },
    ExpressionAttributeValues: {
      ":id": "7fd9a81b-7a7c-4cfb-9c84-25dc2798a8f7",
      ":text": itemText,
      ":finishval": true,
      ":ca": 32432432423
    },
    ConditionExpression: `attribute_not_exists(id)`,
  };
Run Code Online (Sandbox Code Playgroud)

Har*_* KM 7

总长DR

\n

对于您的项目的当前结构,这是不可能的。fa将&更改pa为字符串集,去掉finish: true& 使用 ADD 更新表达式。

\n
\n

对于您的项目的当前结构,这是不可能的。这就是为什么 \xe2\x80\x94 为了满足您的要求,UpdateExpression需要采用以下形式:

\n
if "fa" exists, add {"papa":"dsfadsf"} to it\nelse, create new "fa"={"papa":"dsfadsf"}\n
Run Code Online (Sandbox Code Playgroud)\n

在所有DynamoDB 更新表达式中,只有 SET 和 ADD 可用于此场景。

\n

由于以下原因,上述if else条件无法用 with SET 表示:UpdateExpression

\n
    \n
  • SET fa.papa = \'dsfadsf\'如果存在,则会更新fa,但如果不存在,则会收到错误The document path provided in the update expression is invalid for update

    \n
  • \n
  • SET fa = {"papa":"dsfadsf"}将创建新的fa但如果存在则覆盖它。

    \n
  • \n
\n

如果您尝试将 ADD 和 SET 组合起来以实现上述if else条件,例如ADD fa {} SET fa.papa = dsfadsf,您会收到错误Two document paths overlap with each other; must remove or rewrite one of these paths

\n

所以我们现在只剩下 ADD 表达式,但 ADD 只适用于集合。因此,如果您有能力将fa&的内容转换pa为字符串集,您就可以实现“一次性创建或更新”的目标。其工作原理如下:

\n

原始项目结构必须是:

\n
{\n  "ca": 32432432423,\n  "fa": [\n    "apple:76-100",\n    "yolo:0-25"\n  ],\n  "id": "dsfadsf",\n  "pa": [\n    "key:9e66"\n  ]\n}\n
Run Code Online (Sandbox Code Playgroud)\n

在 DynamoDB JSON 中,即:

\n
{\n  "ca": {\n    "N": "32432432423"\n  },\n  "fa": {\n    "SS": [\n      "apple:76-100",\n      "yolo:0-25"\n    ]\n  },\n  "id": {\n    "S": "dsfadsf"\n  },\n  "pa": {\n    "SS": [\n      "key:9e66"\n    ]\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

现在,使用以下代码:

\n
let AWS = require("aws-sdk")\nlet docClient = new AWS.DynamoDB.DocumentClient()\ndocClient.update({\n    TableName: "my-table",\n    Key: { id: "dsfadsf" },\n    UpdateExpression: `ADD fa :fa, pa :pa SET ca = :ca`,\n    ExpressionAttributeValues: {\n        ":fa": docClient.createSet(["papa:dsfadsf"]),\n        ":pa": docClient.createSet(["finished"]),\n        ":ca": 32432432423\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

如果带有“dsfadsf”的项目id已存在,则会按如下方式更新:

\n
{\n  "ca": {\n    "N": "32432432423"\n  },\n  "fa": {\n    "SS": [\n      "apple:76-100",\n      "papa:dsfadsf",\n      "yolo:0-25"\n    ]\n  },\n  "id": {\n    "S": "dsfadsf"\n  },\n  "pa": {\n    "SS": [\n      "finished",\n      "key:9e66"\n    ]\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

如果带有“dsfadsf”的项目id不存在,则按如下方式创建:

\n
{\n  "ca": {\n    "N": "32432432423"\n  },\n  "fa": {\n    "SS": [\n      "papa:dsfadsf"\n    ]\n  },\n  "id": {\n    "S": "dsfadsf"\n  },\n  "pa": {\n    "SS": [\n      "finished"\n    ]\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n