Home Articles

DynamoDB高级扫描 - JAVA

Asked
Viewed 1903 times
1

我需要通过子字段JSON扫描表,它位于一列中 . 不幸的是,我无法在Java中找到任何示例,也不知道是否可能 .

这是我的数据,这个json代表对象 - 在dynamodb中有一行 . json代表3个java类: - 包含类城市的主类和一些字符串记录 - 城市包含类路

是否可以扫描数据库并找到mainName =“xyz”的记录并拥有一个名为“Rockingham”的城市记录

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

“house”:{“huseName”:“Wendy Carson”}}

我有一些这样的和这项工作,但这还不足以查询正确的数据 . 表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);

2 Answers

  • 0

    如果您通过_1837620查询,则您的数据模型必须考虑到这一点 . 我建议每个表项目有一个城市:

    {
    "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);
    

    作为第二个选项,您可以定义两个表:

    Table A

    主键类型:哈希键键范围键

    哈希键: cityName 范围键: Id (参考表B项)

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

    Table B

    主键类型:哈希键

    哈希键: Id

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

    检索城市项目后,您将通过Id通过 QueryGetItemBatchGetItem 查询表B.

    这两个选项都允许您使用 Query 操作而不是 Scan ,从而使更简单的查询具有更好的性能和更低的成本:

    扫描操作始终扫描整个表或二级索引,然后过滤掉值以提供所需的结果,实质上是添加了从结果集中删除数据的额外步骤 . 如果可能,请避免在大型表或索引上使用扫描操作,并使用可删除许多结果的过滤器 . 此外,随着表或索引的增长,扫描操作会变慢 . “扫描”操作会检查所请求值的每个项目,并且可以在单个操作中用尽大型表或索引的预配置吞吐量 . 为了缩短响应时间,请设计表和索引,以便应用程序可以使用Query而不是Scan . (对于表,您还可以考虑使用GetItem和BatchGetItem API . ) .

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

  • 0

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

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

Related