2015-04-02 94 views
1

我需要通过位于一列中的子字段JSON扫描表。不幸的是,我无法在Java中找到任何地方的例子,也不知道它是否可能。DynamoDB高级扫描 - JAVA

这是我的数据,这个json表示对象 - dynamodb中的一行。 JSON的代表3 Java类: - 包含级城市和一些串记录 主类 - 城市包含一类道路

是否可以扫描数据库,并找到mainName =“XYZ”的记录,已经被称为 “罗金厄姆”

{ 
"Id": "9", 
"mainName": "xyz", 
"floatVariable": 228.3, 
"city": [ 
{ 
    "name": "Rockingham", 
    "road": [ 
    { 
     "roadName": "Traci", 
     "roadLength": 118 
    }, 
    { 
     "roadName": "Watkins", 
     "roadLength": 30 
    } 
    ] 
} 
], 

“房子” 一个城市的记录:{ “huseName”: “温迪·卡森” }}

我有一些像这样,这工作,但这个为n不足以查询正确的数据。 Table table = dynamoDB.getTable(tableName);

 Map<String, Object> expressionAttributeValues = new HashMap<String, Object>(); 
     expressionAttributeValues.put(":pr", 300); 

     ItemCollection<ScanOutcome> items = table.scan(
       "floatVariable < :pr", //FilterExpression 
       "Id, mainName, floatVariable, city" , //ProjectionExpression 
       null, //ExpressionAttributeNames - not used in this example 
       expressionAttributeValues); 

     System.out.println("Scan of " + tableName + " for items with a price less than 300."); 
     Iterator<Item> iterator = items.iterator(); 
     while (iterator.hasNext()) { 
      System.out.println(iterator.next().toJSONPretty()); 
     } 

我在php中看到了一个这样的例子,但不幸的是它在Java中不起作用。

ItemCollection<ScanOutcome> items = table.scan(
      " cites.name = :dupa ", //FilterExpression 
      "Id, mainName, floatVariable, city", //ProjectionExpression 
      null, //ExpressionAttributeNames - not used in this example 
      expressionAttributeValues); 
+0

“cites.name =:DUPA”,// FilterExpression我想写“city.name” – Wojciech 2015-04-02 10:44:38

回答

0

如果您要查询city.name您的数据模型必须考虑到这一点。我会建议有每桌项目一个城:

{ 
"Id": "9", 
"mainName": "xyz", 
"cityName": "Rockingham", 
"floatVariable": 228.3, 
"road": [ 
    { 
     "roadName": "Traci", 
     "roadLength": 118 
    }, 
    { 
     "roadName": "Watkins", 
     "roadLength": 30 
    } 
    ] 
} 
]} 

散列键将是cityName属性和范围键的任何其他属性会导致主键(哈希+范围键)唯一的,例如: Id

QuerySpec querySpec = new QuerySpec() 
         .withHashKey("cityName", "Rockingham") 
         .withProjectionExpression("Id, mainName, floatVariable, road"); 

ItemCollection<QueryOutcome> items = table.query(querySpec); 

正如你可以定义两个表第二个选项:

表A

主键类型:散列键+ RANGE键

散列关键字:cityName 范围重点: Id(参考表B项)

{ 
    "cityName": "Rockingham", 
    "Id" : 9, 
    "road": [ 
     { 
      "roadName": "Traci", 
      "roadLength": 118 
     }, 
     { 
      "roadName": "Watkins", 
      "roadLength": 30 
     } 
     ] 
    } 
    ]} 

表B

主键类型:散列键

散列关键字:Id

{ 
    "Id": "9", 
    "mainName": "xyz", 
    "floatVariable": 228.3 
} 

检索城市的项目,你会被标识通过Query查询表B之后,GetItemBatchGetItem

两个选项将允许您使用Query操作,而不是Scan,有效地简化了查询具有更好的性能和更低的成本:

扫描操作始终扫描整个表或辅助索引, 然后过滤掉值来提供期望的结果,实质上 增加了从结果集中移除数据的额外步骤。如果可能,避免 在大型表或索引上使用扫描操作,并使用筛选器 删除许多结果。另外,随着表格或索引的增长,扫描操作会减慢。扫描操作检查每个项目的 所请求的值,并且可以在单个操作中耗尽大规模表或索引的预配置吞吐量。为了缩短响应时间, 会设计您的表格和索引,以便您的应用程序可以使用查询 而不是扫描。 (对于表格,您也可以考虑使用GetItem 和BatchGetItem API。)。

来源:http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html

0

城市属性是一个不同长度的列表?如果你想使用服务器端过滤,你需要枚举你想检查的列表中的每个元素。

或者,您可以维护一个单独的城市名称列表,并在该属性上使用“contains”运算符。

+0

确定现在我知道,我不能在二级属性和唯一扫描查询方法很快,值得在我的应用程序中使用。 (仅扫描报告) – Wojciech 2015-06-22 20:41:21