【问题标题】:DynamoDB: How can I create a table with nested JSON structure?DynamoDB:如何创建具有嵌套 JSON 结构的表?
【发布时间】:2014-11-24 22:02:30
【问题描述】:

我想在 dynamoDB 中创建一个具有以下结构的表。

{
  "CartId": 123,
  "UserId": 356,
  "CartItems": [
    {
      "ProductId": 100,
      "Quantity": 50
    },
    {
      "ProductId": 121,
      "Quantity": 51
    }
  ]
}

在教程和文档中到处都说我们只能在表格中拥有以下类型的属性:

  1. 字符串集

  2. 一组数字

  3. 二进制集

我想不出在 DynamoDB 中存储上述结构的方法。你能帮忙吗?

我正在使用 java 的对象映射器 Api。如果您还可以告诉我如何创建一个可以映射到这个特定表结构的类,那就太好了。

【问题讨论】:

    标签: java json amazon-dynamodb


    【解决方案1】:

    如果你有一个字符串中的 JSON,你可以简单地调用

    table.putItem(Item.fromJSON(jsonString));
    

    JSON 需要包含分区和排序键的键/值。对于条件看跌期权,使用

    table.putItem(Item.fromJSON(jsonString), conditionString, nameMap, valueMap)
    

    【讨论】:

      【解决方案2】:

      最简单的方法是使用@DynamoDBDocument

      1. 添加 Maven 依赖项
      <dependency>
              <groupId>com.amazonaws</groupId>
              <artifactId>aws-java-sdk-dynamodb</artifactId>
              <version>1.11.186</version>
      </dependency>
      
      1. 创建 POJO
      @DynamoDBTable(tableName = "Customer")
      public class Customer
      { 
          @DynamoDBHashKey
          @DynamoDBAutoGeneratedKey
          private String id;
      
          private String firstName;
      
          private List<Foo> fooList;
      }
      
      @DynamoDBDocument
      public static class Foo {
          private String name;
      }
      
      1. 创建存储库
      @EnableScan
      public interface CustomerRepository extends CrudRepository<Customer,String>
      

      然后拨打customerRepository.save(customer)。结果会是这样的:

      {
        "firstName": "Test",
        "fooList": [
          {
            "name": "foo"
          },
          {
            "name": "foo2"
          }
        ],
        "id": "e57dd681-8608-4712-a39a-f3e0f31a5e27"
      }
      

      【讨论】:

      • 嗨,当我们使用这个解决方案时,如果我们向内部类添加新字段会发生什么情况,它们会出现在 dynamo db 中吗?
      • 是的,它会在那里
      • 如何使用 @DynamoDBDocument 在 pojo 中映射通用 json ..就像我有不同值对象的键值对。
      【解决方案3】:

      发布到一个老问题,因为我认为解决方案不容易找到。希望这对某人有所帮助。

      第 1 步:创建一个反映所需结构的复杂 Java 对象。

      List<HashMap<String, Integer>> cartItems = new ArrayList<HashMap<String, Integer>>();
      HashMap<String, Integer> item1 = new HashMap<String, Integer>();
      item1.put("ProductId", 100);
      item1.put("Quantity", 50);
      cartItems.add(item1);
      HashMap<String, Integer> item2 = new HashMap<String, Integer>();
      item2.put("ProductId", 121);
      item2.put("Quantity", 51);
      cartItems.add(item2);
      

      第 2 步:使用复杂对象更新 DynamoDB 项目。

      我使用辅助方法:

      private void updateAttribute(int id, String newAttribute, Object newValue){
          Map<String, Object> newValues = new HashMap<String, Object>();
          newValues.put(":value", newValue);
      
          UpdateItemSpec updateItemSpec = new UpdateItemSpec()
                  .withPrimaryKey("id", id)
                  .withUpdateExpression("set " + newAttribute + " = :value")
                  .withValueMap(newValues);
      
          siteTable.updateItem(updateItemSpec);
      }
      

      然后这样调用:

      updateAttribute(123, "CartItems", cartItems);
      

      新添加的购物车项目属性在 DynamoDB 中显示如下:

      {
       "CartItems": [
         {
           "ProductId": 100,
           "Quantity": 50
         },
         {
           "ProductId": 121,
           "Quantity": 51
         }
       ]
      }
      

      我还没有测试过 upsert 场景。过去,似乎不存在 upsert 功能:https://forums.aws.amazon.com/thread.jspa?threadID=162907

      关于深度嵌套项的读取:http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.AccessingItemAttributes.html#DocumentPaths

      【讨论】:

        【解决方案4】:

        聚会迟到了,但想分享一下。 通过在我的 Java 实体中定义如下的列属性,我能够存储深度嵌套的 Json Doc。

        @DynamoDBAttribute
        @DynamoDBTypeConvertedJson
        private List<Map<String,Object>> pageData;
        

        输入Json:

         {
            "userId": 359628,
            "platform": "learn-web",
            "inactive_duration": 0,
            "total_time": 15,
            "device_type": "web",
            "page_data": [{
                "page_details": {
                    "page_type": "segmentView",
                    "time": 15,
                    "segment_id": 65590,
                    "session_id": 13140,
                    "module_id": 4363
                },
                "items": [{
                    "type": "component",
                    "id": 267307,
                    "sub_type": "video",
                    "time": 10,
                    "metadata": {
                        "lastPlaybackRate": 1,
                        "currentTime": 0,
                        "isLocked": false,
                        "video": {
                            "videoType": "BRIGHTCOVE",
                            "viewingTime": 156,
                            "videoSize": 7120441,
                            "url": "5378655747001",
                            "URL": "5378655747001"
                        }
                    }
                }]
            }]
        }
        

        As stored in Dynamo DB-Snap

        【讨论】:

          【解决方案5】:

          不确定这些数据类型在被问到这个问题时是否可用(很有可能它们不可用),但这些天你会为 CartItems 使用 List 数据类型,并且每个购物车项目都是 Map数据类型。

          参考:DynamoDB Data Types

          【讨论】:

            【解决方案6】:

            您可以将 JSON 作为字符串存储在 Dynamodb 中。这完全取决于您要对数据做什么以及如何检索它。

            例如,DynamoDB Java API 引入了 Marshaller 对象,可将任何 Java 对象转换为字符串,以便您可以存储它并从 DynamoDB 属性自动获取它。

            【讨论】:

            • 我们怎样才能做到这一点?
            • 您说 DynamoDB 需要字符串集,但它也可以保存字符串。您使用的是哪种 SDK/编程语言?
            • 我有包含嵌套对象的 json 文件,我正在尝试将它导入到我在 aws dynamo 中创建的表中,我正在运行 aws dynamodb put-item 但未能导入数据,有什么帮助吗?
            猜你喜欢
            • 2017-12-14
            • 1970-01-01
            • 1970-01-01
            • 2014-06-08
            • 1970-01-01
            • 2022-11-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多