使用 NodeJS 将新对象附加到 DynamoDB 中的 JSON 数组
Posted
技术标签:
【中文标题】使用 NodeJS 将新对象附加到 DynamoDB 中的 JSON 数组【英文标题】:Append a new object to a JSON Array in DynamoDB using NodeJS 【发布时间】:2017-05-15 00:12:32 【问题描述】:我正在使用 JSON 结构来存储一个人的详细信息。基本上姓名、电话、注册时间戳等都是其他属性,主键是电子邮件地址。
markedLocations、visitedLocations、searchHistory 和推荐是 AWS 所称的列表或地图。它将包含许多 JSON 对象。
JSON 结构-
"name":"Mama Miya",
"phone":"9383883223",
"registeredTimestamp":"some-time",
"lastActiveTimestamp":"some-time",
"signinType":"facebook",
"additionalSigninData":
"key1":"value1",
"key2":"value2"
,
"markedLocations":[
"latitude":"77.33",
"longitude":"12.33",
"name":"Home",
"description":"my new home",
"placeid":"55334433",
"image":"url/abc.png"
]
从应用程序中,如果用户访问一个新位置,我需要将一个新的 JSON 对象添加到 markedLocations。 所以标记的位置应该看起来像-
"markedLocations":[
"latitude":"77.33",
"longitude":"12.33",
"name":"Home",
"description":"my new home",
"placeid":"55334433",
"image":"url/abc.png"
,
"latitude":"22.11",
"longitude":"22.55",
"name":"Ocean",
"description":"Ocean",
"placeid":"32423423",
"image":"url/icean.png"
]
代码/架构-
var item =
'email': 'S': req.body.email,
'phone': 'S': req.body.phone,
'registeredTimestamp': 'S': req.body.registeredTimestamp,
'lastActiveTimestamp': 'S': req.body.lastActiveTimestamp,
'signinType': 'S': req.body.signinType,
'version': 'S': req.body.version,
'markedLocations': 'L': req.body.markedLocations
;
我查过了-
在 DynamoDB 中,如何使用 Java link 将元素附加到列表字段中@
更新 AWS dynamoDB 中的 JSON 数组link
使用 Node Js link在 Dynamo db 中更新 Set
如何使用 nodejs 更新 dynamoDB 中的项目? link
并检查了 AWS 文档中的 UpdateItem API。我没有找到任何与我的问题/疑问相关的内容。
请告诉我是否有办法在 NodeJS 中将 JSON 数组附加到一个新的 JSON 对象?我无法继续执行相同的操作。
或
我是否应该为每个数组创建单独的表,并将电子邮件作为主键,将时间戳作为排序键并继续?
PS:我是 DynamoDB 的新手,我之前使用过 MongoDB,并且有一些方法可以使用那里的 JSON 数组和对象。在这里找不到路。
【问题讨论】:
你知道如何用 javascript 来做吗?这就是你要做的。 Node.JS 使用 Javascript。 @RobertHarvey 不。我不知道如何在 JS 中解决这个问题。整个 AWS 文档都有使用 Java、php 和 .Net 的示例和 API 演示。我不确定要使用什么 API 或如何构建代码。我列出的 *** 问题要么根本没有答案,要么主要是为了替换现有值。我需要追加到现有数组。 听起来您正试图在某个地方找到一个 API 或库来进行应该可以在 Javascript 中轻松完成的简单操作。看看this post,尤其是this answer。您不需要 NodeJS、Dynamo 或其他任何东西来完成此操作。请注意,该帖子的作者犯了与您相同的错误; 您也不需要 jQuery 来执行此操作。 @RobertHarvey 感谢您纠正我。但是,再次回到这个问题,假设我已经在 DynamoDB 中的数组中有 2 个对象(如前所述的对象文字),我如何将另一个对象附加到它?如何在数据库上执行splice
或push
操作?这不可能吧?
@RobertHarvey 用架构结构更新了我的问题。
【参考方案1】:
在UpdateExpression 中一起使用list_append()
和if_not_exists()
以附加到可能不存在的列表列:
var AWS = require('aws-sdk')
var DB = new AWS.DynamoDB.DocumentClient()
function appendMarkedLocation (personId, location)
return DB.update(
TableName: 'people',
Key: id: personId ,
ReturnValues: 'ALL_NEW',
UpdateExpression: 'set #markedLocations = list_append(if_not_exists(#markedLocations, :empty_list), :location)',
ExpressionAttributeNames:
'#markedLocations': 'markedLocations'
,
ExpressionAttributeValues:
':location': [location],
':empty_list': []
).promise()
appendMarkedLocation('somePeronId',
latitude: '22.11',
longitude: '22.55',
name: 'Ocean',
description: 'Ocean',
placeid: '32423423',
image: 'url/icean.png'
).then(console.log)
【讨论】:
这正是我一直在寻找的东西。将对其进行测试和更新。非常感谢。 请告诉我我应该为数组中的每个对象使用什么属性类型?它应该是一个列表吗? @bozzmob 如果您像我在回答中那样使用 DocumentClient,那么您根本不需要关心 DyanmoDB 内部类型。 DocumentClient 会将markedLocations
List 中的每个项目在内部转换为 Map 类型。所以markedLocations
最终会成为一个地图列表。
我没有意识到要附加的对象必须包装在一个数组中。它看起来更像是数组合并而不是追加。
@PhilD。合并意味着“目标”数组中的值可以被替换/覆盖。这里情况不同。我同意一个更好的术语可能是list_concat
。但是在任何一种情况下,这个函数都将一个数组作为输入,这使得它比只附加一个项目的函数更灵活。这样,如果您要附加多个项目,则可以在一次调用中完成,而不是多次。以上是关于使用 NodeJS 将新对象附加到 DynamoDB 中的 JSON 数组的主要内容,如果未能解决你的问题,请参考以下文章
Jackson 不会将新的 JSON 对象附加到现有的 Json 文件中