【问题标题】:updating a JSON array in AWS dynamoDB更新 AWS dynamoDB 中的 JSON 数组
【发布时间】:2017-03-12 01:49:27
【问题描述】:

我的文档如下所示:

{
  "data": {
      "eventId": "20161029125458-df-d",
      "name": "first",
      "purpose": "test",
      "location": "yokohama",
      "dateArray": [],
      "attendees": [
        {
          "attendeeId": "2016102973634-df",
          "attendeeName": "lakshman",
          "personalizedDateSelection": {}
        },
        {
          "attendeeId": "2016102973634-tyyu",
          "attendeeName": "diwaakar",
          "personalizedDateSelection": {}
        }
      ]
    }
}

比如说,我需要用 attendeeId: 2016102973634-df 更新参加者 JSON 数组。我尝试了很多方法使用更新和条件表达式,但没有成功。

这是我的尝试:

const params = {
  TableName: "event",
  Key: {
    "eventId": eventId 
  },
  UpdateExpression: "SET attendees[???] = ",
  ConditionExpression: attendees.attendeeId = "2016102973634-df", 
  ExpressionAttributeValues: {
    ":attendee" : attendeeList
  },
  ReturnValues: "ALL_NEW"
};


dynamo.update(params, (err, data) => {
  if (err) {
    return reject(err);
  }
  console.log(data.Attributes);
});

找不到用于更新数组中的 Json 的任何资源。

@notionquest 发表评论后: - 没有使用任何 JsonMarshaller。最初我将空数组添加到参加者字段,如下所示:

{
  "eventId": "20161029125458-df-d",
  "name": "first",
  "purpose": "test",
  "location": "yokohama",
  "dateArray": [],
  "attendees": []
}

然后当新的 attendee 出现时,我将其添加到 attendees 属性中,如下所示:

const attendee = {
  "attendeeName": "user1",
  "personalizedDateSelection": {"today": "free"}
}
const attendeeList = [attendee];
const eventId = "20161029125458-df-d";


const params = {
  TableName: "event",
  Key: {
    "eventId": eventId
  },
  UpdateExpression: "SET attendees = list_append(attendees, :attendee)",
  ExpressionAttributeValues: {
    ":attendee" : attendeeList
  },
  ReturnValues: "ALL_NEW"
};


dynamo.update(params, (err, data) => {
  if (err) {
    return reject(err);
  }
  console.log("in update dynamo");
  console.log(data.Attributes);
});

正如您在上面的 sn-ps 中看到的,最初我添加了空的 [] 数组,并使用上面的代码添加了一个新的与会者。现在,如何更新数组中的特定 JSON。如果你说这是不可能的,我还能尝试什么?

我应该试试这个:

  1. 获取完整的 JSON。
  2. 操作 JSOn 并在我的 nodeJS 中更改我想要的内容。
  3. 然后将新的 JSON 更新为 dynamoDB。
  4. 但这会消耗两次对 dynamoDB 的调用,这似乎是低效的。

想知道是否有任何圆形方式?

【问题讨论】:

  • 您是否使用 JsonMarshaller 在 DynamoDB 中将数据保存为 JSON?如果是,则 API 没有更新 JSON 数据的选项。
  • @notionquest 我已经更新了我如何将 Json 插入到数组中的问题。想知道你的想法!!!

标签: arrays json amazon-web-services amazon-dynamodb dynamo-local


【解决方案1】:

您可以存储列表的索引。在更新列表时,我们可以使用它们。例如,

{


"data": {
      "eventId": "20161029125458-df-d",
      "name": "first",
      "purpose": "test",
      "location": "yokohama",
      "dateArray": [],
      "attendees": [
        {  
          "index":0,  
          "attendeeId": "2016102973634-df",
          "attendeeName": "lakshman",
          "personalizedDateSelection": {}
        },
        {
           "index":1,
          "attendeeId": "2016102973634-tyyu",
          "attendeeName": "diwaakar",
          "personalizedDateSelection": {}
        }
      ]
    }
}
const params = {
  TableName: "event",
  Key: {
    "eventId": eventId 
  },
  UpdateExpression: "SET attendees[attendee.index].attendeeName = :value",
  ExpressionAttributeValues: {
    ":value" : {"S":"karthik"}
  },
  ReturnValues: "ALL_NEW"
};


dynamo.update(params, (err, data) => {
  if (err) {
    return reject(err);
  }
  console.log(data.Attributes);
});

【讨论】:

  • 您是从哪里获得的参加者索引的?这个“与会者”似乎不是架构的一部分。如果它应该是一个变量,它不应该在引号之外吗?
  • 有索引是任何默认 atrr 我在 doc 之类的索引中没有找到关于它的索引,我们可以使用其他属性,例如参加者 ID
【解决方案2】:

更新查询示例:

数据结构(保存在 DynamoDB 中)

{
  tenant_id: 'tenant_1',
  users: {
    user1: {
      _id: 'user1',
      email_address: 'test_email_1@gmail.com'
    },
    user2: {
      _id: 'user2',
      email_address: 'test_email_2@gmail.com'
    }
  }
}

更新数据(在参数中使用)

var user = {
 email_address: 'updated@gmail.com'
}

参数

var params = {
    TableName: 'tenant-Master',
    Key: {
       "tenant_id": 'tenant_1'
    },
    UpdateExpression: "set #users.user1 = :value",
    ExpressionAttributeNames: {
    "#users": "users"
    },
    ExpressionAttributeValues: {
    ":value": user,
    },
 };

解释

通过从地图数组切换到地图地图,我们现在可以使用UpdateExpression: "set #users.user1 = :value" 来更新ID 为user1 的用户地图上的嵌套对象。

注意:此方法将REPLACEusers.user1 处的整个地图对象。如果您想保留预先存在的数据,则需要进行一些更改。

【讨论】:

  • 如果你只需要“.user1”属性(使用“#user.user1 = :value”)来更改对象内容,为什么你还有属性_id?
【解决方案3】:

我找不到任何查询和更新 JSON 数组的答案。我认为这可能是 AWS 不允许这些功能的盈利动机。如果您需要查询除主键之外的特定 ID,则需要制作具有成本效益的二级索引。此二级索引成本是 dyn 的额外成本 amoDB 表开销。

由于我不想为二级索引支付额外费用,因此我将 dynamoDB 架构更改为以下内容:

{
  "data": {
      "eventId": "20161029125458-df-d",
      "name": "first",
      "purpose": "test",
      "location": "yokohama",
      "dateArray": [],
      "attendees": {
        "2016102973634-df": {
          "attendeeId": "2016102973634-df",
          "attendeeName": "lakshman",
          "personalizedDateSelection": {}
        },
        "2016102973777-df": {
          "attendeeId": "2016102973777-df",
          "attendeeName": "ffff",
          "personalizedDateSelection": {}
        }
      }
    }
}

将与会者从 [] 更改为 {}。这让我可以灵活地查询特定的 attendeeId 并更改与之关联的整个 JSON。尽管这是一个多余的步骤,但我不想在我的爱好项目上花费额外的钱。

【讨论】:

  • 您能否发布示例查询以更新嵌套 json?如何更新“attendees.2016102973634-df”json?以及如何更新“attendees.2016102973634-df.attendeeName”?
猜你喜欢
  • 1970-01-01
  • 2017-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-24
  • 2019-04-21
相关资源
最近更新 更多