web-dev-qa-db-fra.com

DynamoDB: comment utiliser un filtre de requête pour vérifier les conditions dans une carte

J'ai une table et la structure ressemble à ceci:

DynamoDB document

Lorsque je fais une requête, je voudrais pouvoir faire un filtre de requête sur la carte de données; mais je ne sais pas exactement comment configurer la requête.

Voici ce que j'ai jusqu'à présent:

HashMap<String, AttributeValue> map = new HashMap<String, AttributeValue>();
map.put("byUserId", new AttributeValue().withS("vl49uga5ljjcoln65rcaspmg8u"));

queryExpression
    .withQueryFilterEntry("data", new Condition()
        .withAttributeValueList(new AttributeValue().withM(map))
        .withComparisonOperator(ComparisonOperator.CONTAINS));

mais la façon dont je construis le filtre n'est pas correcte et je continue à rencontrer l'erreur suivante:

Exception in thread "main" com.amazonaws.AmazonServiceException: One or more parameter values were invalid: ComparisonOperator CONTAINS is not valid for M AttributeValue type (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: CHIOME68L1HVGO81URD7CIOS6BVV4KQNSO5AEMVJF66Q9ASUAAJG)
    at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.Java:1077)
    at com.amazonaws.http.AmazonHttpClient.executeOneRequest(AmazonHttpClient.Java:725)
    at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.Java:460)
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.Java:295)
    at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.invoke(AmazonDynamoDBClient.Java:3106)
    at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.query(AmazonDynamoDBClient.Java:1118)

Alors, quel est un opérateur de comparaison que je devrais utiliser (puisque IN est pour les types de liste), et comment puis-je créer le filtre de requête afin que je puisse spécifier une comparaison à l'intérieur de la MAP.

Merci!

13
ThePedestrian

Essayez de comparer l'attribut de carte data.byUserId au lieu de toute la structure de la carte:

Table table = dynamoDB.getTable(tableName);

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


QuerySpec spec = new QuerySpec()
    .withHashKey("HashKeyAttribute", "HashKeyAttributeValue")
    .withFilterExpression("data.byUserId = :x")
    .withValueMap(expressionAttributeValues);


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

Iterator<Item> iterator = items.iterator();

while (iterator.hasNext()) {
    System.out.println(iterator.next().toJSONPretty());
}

Quelques directives importantes:

  1. Assurez-vous que la variable tableName a le nom de table correct représenté par un string.

  2. Assurez-vous de remplacer la chaîne HashKeyAttribute par le nom d'attribut qui représente votre Hash Key.

  3. Assurez-vous de remplacer la chaîne HashKeyAttributeValue par la valeur qui représente la clé de hachage que vous souhaitez faire correspondre.

  4. Assurez-vous que l'enregistrement correspondant a le data.byUserId avec la valeur fournie dans l'expression de comparaison. Dans l'exemple, la valeur "vl49uga5ljjcoln65rcaspmg8u" a été fourni.

Voici un autre exemple ayant l'attribut id comme clé de hachage:

Table table = dynamoDB.getTable(tableName);

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


QuerySpec spec = new QuerySpec()
    .withHashKey("id", "25g77vmummpr4mc5mb9vq36q43")
    .withFilterExpression("data.byUserId = :x")
    .withValueMap(expressionAttributeValues);


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

Iterator<Item> iterator = items.iterator();

while (iterator.hasNext()) {
    System.out.println(iterator.next().toJSONPretty());
}
9
bsd