【问题标题】:DynamoDB advanced scan - JAVADynamoDB 高级扫描 - JAVA
【发布时间】:2015-04-02 10:14:47
【问题描述】:

我需要按位于一列中的子字段 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
    }
  ]
 }
],

“房子”:{ “huseName”:“温迪·卡森” } }

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

【问题讨论】:

  • " cites.name = :dupa ", //FilterExpression 我想写“city.name”

标签: java json amazon-dynamodb


【解决方案1】:

如果您通过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

主键类型:Hash Key + Range Key

哈希键: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
}

检索城市项目后,您将通过 QueryGetItemBatchGetItem 按 ID 查询表 B。

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

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 好的,现在我知道我无法扫描二级属性,只有查询方法快速且值得在我的应用程序中使用。 (仅扫描报告)
    猜你喜欢
    • 1970-01-01
    • 2021-05-25
    • 2016-10-15
    • 1970-01-01
    • 1970-01-01
    • 2020-07-01
    • 2012-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多