【问题标题】:Retrieving a subset of a JSON object stored in Dynamo检索存储在 Dynamo 中的 JSON 对象的子集
【发布时间】:2016-10-06 18:42:44
【问题描述】:

目前是否可以检索存储在 Dynamo 中的 json 对象的子集?例如,我有一个 JSON 类型的名为 record 的属性,它是一个 JSON 对象数组:

records:
[
    {"K1": "V1" },
    {"K2": "V2" },
    {"K3": "V3" },
    {"K4": "V4" }
]

我将它们以 JSON 格式存储在 Dynamo 中。我想知道我是否只能检索键值对 1 到 2 而不能检索第三和第四对?我不确定是否可以提供特定的过滤器表达式来执行此操作。

如果可能的话,我很想听听关于如何做到这一点的方法?

谢谢!

【问题讨论】:

  • “记录”属性的 DynamoDB 数据类型是什么?是地图吗?
  • 我在考虑两种类型 - 一种是使用 gson 之类的序列化后的 json 字符串。第二种选择是将其序列化,但将其存储为列表而不是单个字符串。

标签: java json amazon-dynamodb


【解决方案1】:

首先,DynamoDB 中没有 JSON 数据类型。如果您的意思是将数据存储为 DynamoDB 数据类型 MAP,那么以下解决方案应该适合您。

简而言之,过滤器表达式应该如下所示:-

FilterExpression : 'records.K1 = :recordsK1Value and records.K2 = :recordsK2Value'

如果您只需要输出“records.K1”和“records.K2”,则可以使用项目表达式。

ProjectionExpression : 'records.K1, records.K2'

完整代码:-

public List<String> queryMoviesAndFilterByMapAttribute() {

    List<String> moviesJsonList = new ArrayList<>();

    DynamoDB dynamoDB = new DynamoDB(dynamoDBClient);

    Table table = dynamoDB.getTable("Movies");

    QuerySpec querySpec = new QuerySpec();

    querySpec.withKeyConditionExpression("yearkey = :yearval and title = :titleval")
            //.withProjectionExpression("records.K1, records.K2")
            .withFilterExpression("records.K1 = :recordsK1Value and records.K2 = :recordsK2Value").withValueMap(
                    new ValueMap().withNumber(":yearval", 1991).withString(":titleval", "Movie with map attribute")
                            .withString(":recordsK1Value", "V1").withString(":recordsK2Value", "V2"));

    IteratorSupport<Item, QueryOutcome> iterator = table.query(querySpec).iterator();

    while (iterator.hasNext()) {
        Item movieItem = iterator.next();
        System.out.println("Movie data ====================>" + movieItem.toJSONPretty());
        moviesJsonList.add(movieItem.toJSON());
    }

    return moviesJsonList;

}

包含所有字段的示例输出(即没有项目表达式):-

Movie data ====================>{
  "yearkey" : 1991,
  "records" : {
    "K1" : "V1",
    "K2" : "V2",
    "K3" : "V3",
    "K4" : "V4"
  },
  "title" : "Movie with map attribute"
}

取消注释项目表达式后的示例输出:-

请注意,输出中不存在其他字段,例如 yearkey、title、K3 和 K4。

Movie data ====================>{
  "records" : {
    "K1" : "V1",
    "K2" : "V2"
  }
}

【讨论】:

  • 非常感谢您的回复。这真的很有帮助。我有一个问题。此实现适用于地图。是否可以检索类似方式的列表的子集?我猜想在 projectionExpression 中有键的概念会有所不同吗?我只想知道它是否可能,不希望你不厌其烦地完全解决它。谢谢!
  • 是的,只要是字符串值列表就可以。示例:- FilterExpression : 'contains (records, :recordsK1Value)', ProjectionExpression : 'records[0], records[1]',
  • 太棒了!非常感谢您的帮助!
猜你喜欢
  • 2013-03-08
  • 2013-10-15
  • 2011-07-26
  • 1970-01-01
  • 2011-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-13
相关资源
最近更新 更多