AWS DynamoDB Scan and FilterExpression using array of hash values

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

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'
  }
}