首页 > 解决方案 > 如何只更新部分 JSON?

问题描述

我有一个 DynamoDB 表:

+--------------------------------------------------+
| Customer ID (Primary Key)|Gamestats (JSON entry) |
+--------------------------------------------------+

JSON:

{
  "Gamestats": [
    {
      "ID": "QuickShootingMode",
      "status": 1
    },
    {
      "ID": "FastReloadMode",  // Just want to update this and not update the entire JSON
      "status": 0
    }
  ],
  "CustomerID": "xyz"
}

我只想更新 JSON 的一部分。最好的方法是什么?例如,将 更新QuickShootingMode为假。

一种方法是调用并获取 JSON,然后迭代 JSON 并更新值,然后将新的 JSON 放回 dynamo DB。这意味着它将进行 2 次调用
A) 获取数据和
B) 将数据放入 DB。

有没有更好的方法可以直接更新数据并避免进行这些额外的网络调用?我可以将 JSON 的每个键转换为 dynamo BD 中的一列,但是如果键的数量增加,那么我最终会得到很多列(这可能是一个糟糕的设计),因此我认为将 JSON 保存在一栏Game stats会更有意义。

Map<String, AttributeValue> key = new HashMap<>();   
    AmazonDynamoDB dynamoDB = dynamoDBClient.getDynamoDB();
    key.put(USER_ID_KEY, new AttributeValue().withS("xyz"));
    key.put("Gamedata", new AttributeValue().withS("some JSON"));
    PutItemRequest request = new PutItemRequest()
            .withTableName(table)
            .withItem(key);

 PutItemResult result = dynamoDB.putItem(request);
 

有没有更好的方法来实现我想要的?

标签: amazon-dynamodb

解决方案


从您的问题看来,您正在存储字符串化的 JSON。如果是这样,对update您没有帮助,但据我所知,存储字符串化 JSON 而不是使用 dynamodb 地图和列表没有任何价值。

您可以使用更新在地图或列表中设置嵌套属性。对 gamestats 属性使用地图而不是列表会更好,因为这样您就不必担心属性的顺序。

以 Gamestats 为地图的 Javascript 示例。

dynamodb.update({
  TableName: table,
  Key: key,
  UpdateExpression: 'SET #gs.#qs.#status = :newStatus',
  ExpressionAttributeNames: {'#gs': 'Gamestats', '#qs': 'QuickShootingMode', '#status': 'status' },
  ExpressionAttributeValues: { ':newStatus': false }
}, callback)

推荐阅读