2014-09-30 139 views
3

我想在dynamoDB中創建一個具有以下結構的表。DynamoDB:如何創建一個嵌套JSON結構的表?

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

無處不在的教程和文件,它說,我們只能有下表中的屬性類型:

  1. 組字符串

  2. 組數字的

  3. 一套二進制

我想不出在DynamoDB中存儲上述結構的方法。你能幫忙嗎?

我使用java的對象映射器Api。如果你也可以告訴我如何創建一個可以映射到這個特定表結構的類,那將是非常好的。

回答

-4

從您提供的JSON結構中,我認爲您正在嘗試使DynamoDB像關係數據庫一樣,當時您應該將DynamoDB看作簡單的平面鍵值存儲。所以,而不是像你建議的表結構,我會把它壓平,並且對於客戶在購物車中的每件商品都有許多行。

例如

Primary hashkey (UserId) | Hash range key (CartId) | ProductId | Qty 
356      123      100   50 
356      123      121   51 

通過這種方式,你可以通過提供的356主鍵獲得一個購物車的所有項目,具有範圍鍵123.這是存儲可轉位和可查詢數據的DynamoDB方式。這確實意味着您要存儲兩個單獨的行,但是。

像這樣的格式有很多優點,特別是它使您能夠在ProductId上創建本地二級索引,以找出有多少客戶將特定產品放入購物車。它也應該很容易看出對象映射器如何與這個表結構一起工作。

+0

嘿非常感謝,你的建議解決了我的問題:)。我現在使用你指定的格式。另外,我的印象是HashKey應該是唯一的。感謝澄清。 – Amit 2014-10-01 23:57:31

+0

相對於您的總數據集,Hashkey應該是唯一的。如果你只有五個用戶,但你有數百萬行,你將遭受性能損失。對於這個特定的用例,主哈希鍵是非唯一的。如果感興趣,您可以閱讀更多關於Amazon DynamoDB如何對數據進行性能分區的內容。 – kurtzbot 2014-10-02 15:19:28

+6

這個答案是錯誤的。 DynamoDB表不能包含具有非唯一主鍵的項目,無論是簡單(僅分區鍵)還是複合(分區鍵和排序鍵)。 *分區密鑰=散列密鑰;排序鍵=範圍鍵 – golem 2016-12-05 01:33:38

1

您可以將JSON作爲字符串存儲在Dynamodb中。這完全取決於您想要如何處理數據以及如何檢索數據。

例如,DynamoDB Java API引入了Marshaller對象,該對象將任何Java對象轉換爲String,因此您可以將其存儲並從DynamoDB屬性中自動獲取它。

+0

我們怎樣才能做到這一點? – Amit 2014-10-01 00:05:08

+0

你說DynamoDB需要一組字符串,但它也可以保存字符串。你使用哪種SDK /編程語言? – 2014-10-01 06:12:13

+0

我正在使用Java – Amit 2014-10-01 06:36:24

0

不確定這些數據類型在詢問這個問題時是否可用(這很可能不是),但現在您將使用List數據類型作爲CartItems,並且每個購物車項目都是Map數據類型。

參考:DynamoDB Data Types

2

發佈到一個老問題,因爲我不認爲解決的辦法也很容易找到。希望這可以幫助某人。

第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

簡單的方法是使用@DynamoDBDocument

  1. 添加Maven的依賴

    <dependency> 
         <groupId>com.amazonaws</groupId> 
         <artifactId>aws-java-sdk-dynamodb</artifactId> 
         <version>1.11.186</version> 
    </dependency> 
    
  2. 創建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; 
    } 
    
  3. 創建一個存儲庫

    @EnableScan 
    public interface CustomerRepository extends CrudRepository<Customer,String> 
    

    然後調用customerRepository.save(customer)。其結果將是這樣的:

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

嗨,當我們使用這個解決方案時,如果我們向內部類添加新字段會發生什麼,它們會出現在Dynamo數據庫中嗎? – Bhargav 2017-12-07 09:10:19

+0

是的,它會在那裏 – sendon1982 2017-12-08 03:45:19