AWS DynamoDB Scan And FilterExpression Using Array Of Hash Values
Answer :
You should make use of the IN
operator. It is also easier to use Placeholders for attribute names and attribute values. I would, however, advise against using a Scan
in this case. It sounds like you already have the hash key attribute values that you want to find, so it would make more sense to use BatchGetItem
.
Anyways, here is how you would do it in Java:
ScanSpec scanSpec = new ScanSpec() .withFilterExpression("#idname in (:val1, :val2, :val3)") .withNameMap(ImmutableMap.of("#idname", "ID")) .withValueMap(ImmutableMap.of(":val1", "123", ":val2", "456", ":val23", "789")); ItemCollection<ScanOutcome> = table.scan(scanSpec);
I would imagine using the Javascript SDK it would be something like this:
var scanParams = { "TableName":"myAwsTable", "AttributesToGet": ['ID','COMMENTS','DATE'], "FilterExpression": '#idname in (:val1, :val2, :val3)', "ExpressionAttributeNames": { '#idname': 'ID' }, "ExpressionAttributeValues": { ':val1': '123', ':val2': '456', ':val3': '789' } }
I had this issue and figured it out by using contains parameter
// Object stored in the DB looks like this: // [ // 'name' => 'myName', // 'age' => '24', // 'gender' => 'Male', // 'visited' => [ // 'countries': ['Canada', 'USA', 'Japan', 'Australia'], // 'last_trip': '2015/12/13', // 'reviews_written': 20 // ] // // ]; $countries = ['Canada', 'USA', 'Japan', 'Australia']; $paramToMatch = '24'; $client->query([ 'TableName' => 'MyDyanmoDB', 'KeyConditions' => [ 'age' => [ 'AttributeValueList' => [ $marshaler->marshalValue($paramToMatch) ], 'ComparisonOperator' => 'EQ' ] ], 'ExpressionAttributeNames' => [ '#visited' => 'visited', '#countries' => 'countries' ], 'ExpressionAttributeValues' => [ ':countries' => $marshaler->marshalValue($countries) ], 'FilterExpression' => 'contains(:countries, #visited.#countries)', ]);
Here's how I was able to use "scan" to get the items with a particular ID ("ContentID") in below example:
var params = { TableName: environment.ddbContentTableName, ProjectionExpression: "Title, ContentId, Link", FilterExpression: "ContentId in (:contentId1, :contentId2, :contentId3, :contentId4)", ExpressionAttributeValues: {":contentId1":102,":contentId2":104,":contentId3":103,":contentId4":101} }; var docClient = new AWS.DynamoDB.DocumentClient(); docClient.scan(params, onQuery);
I can then programmatically construct the FilterExpression and ExpressionAttributeValues based on known values e.g.
// Create the FilterExpression and ExpressionAttributeValues var filterExpression = "ContentId in ("; var expressionAttributeValues = {}; for (var i = 0; i < currentFavorites.length; i++) { var contentIdName = ":contentId"+(i+1); if (i==0) { filterExpression = filterExpression + contentIdName; } else { filterExpression = filterExpression + ", " + contentIdName; } expressionAttributeValues[contentIdName] = currentFavorites[i]; } filterExpression = filterExpression + ")"; var params = { TableName: environment.ddbContentTableName, ProjectionExpression: "Title, ContentId, Link", FilterExpression: filterExpression, ExpressionAttributeValues: expressionAttributeValues }; var docClient = new AWS.DynamoDB.DocumentClient(); docClient.scan(params, onQuery);
Comments
Post a Comment