使用 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 个对象(如前所述的对象文字),我如何将另一个对象附加到它?如何在数据库上执行splicepush 操作?这不可能吧? @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 文件中

使用 jinja2 时如何将新条目添加到字典对象中?

如何使用 python boto3 将新角色权限附加到 aws 中的 iam_role?

如何使用 pandas 将新的数据帧行附加到 csv?

JClouds:如何将新卷附加到 AWS EC2 实例

如何使用 pymongo 将新的值数组附加到 mongodb 中的现有数组文档?