2
votes

My data is stored in a single table "events" in DynamoDB in the following schema with "_id" as hash key and "microtime" as range key (example data below):

{
  "_id": {
    "S": "ae3761b5-b73b-4fb9-ae5a-5cc230b8fa11"
  },
  "data": {
    "M": {
      "name": {
        "S": "Jeff"
      },
      "purchase_value": {
        "N": "25"
      },
      "user_id": {
        "N": "1201"
      }
    }
  },
  "microtime": {
    "N": "14147568808639"
  }
}

I am using AWS PHP SDK 2.7.0 to scan the database based on my filters (in this example, primary hash key "_id"). My code below that works perfectly (returns correct entry):

$client = DynamoDbClient::factory(array(
                'key'    => 'key',
                'secret' => 'secret',
                'region' => 'eu-west-1'
));

$iterator = $client->getIterator('Scan', array(
    'TableName' => 'events',
    'ScanFilter' => array(
        '_id' => array(
            'AttributeValueList' => array(
                array('S' => "ae3761b5-b73b-4fb9-ae5a-5cc230b8fa11")
            ),
            'ComparisonOperator' => 'EQ'
        ),
    )
));

foreach ($iterator as $item) {
  print_r($item);
}

now when I try to scan based on data INSIDE of the "data" element, I can't get any matching entries. Example code below (I am trying to extract all with data.name=Jeff):

$iterator = $client->getIterator('Scan', array(
    'TableName' => 'events',
    'ScanFilter' => array(
        'data.name' => array(
            'AttributeValueList' => array(
                array('S' => "Jeff")
            ),
            'ComparisonOperator' => 'EQ'
        ),
    )
));

foreach ($iterator as $item) {
  print_r($item);
}

Anyone can see any issues with my code, or is it in fact not possible to extract data by comparing values INSIDE of a JSON document? Thanks in advance for any suggestions!

EDIT

I've tried the following code from DynamoDB PHP SDK Documentation (http://docs.aws.amazon.com/aws-sdk-php/v3/api/Aws/DynamoDb/dynamodb-2012-08-10.html#scan) - still no success. I can only retrieve when scanning using primary hash/range key, and any other ("first-level") key, but not using a key from INSIDE of a document (map/list) like in my example. See below:

$iterator = $client->getIterator('Scan', array(
    'TableName' => 'events',
    'ScanFilter' => array(
        'data' => array(
            'AttributeValueList' => array(
                array(
                    'M' => array(
                        'name' => array("S"=>"Jeff"),
                    ),
                ),
            ),
            'ComparisonOperator' => 'EQ',
        ),
    ),
));
2

2 Answers

3
votes

Solution to my issue:

$iterator = $client->getIterator('Scan', array(
    'TableName' => 'event_test2',
    'FilterExpression' => 'event.customer_name = :filter',
    "ExpressionAttributeValues" => array(":filter"=>array("S"=>"Jeff")),
));

More information here: https://forums.aws.amazon.com/thread.jspa?threadID=164470

1
votes

From the API, it seems possible, but I've never actually tried it. That is definitely not the correct syntax though. Look at the Scan API docs for the upcoming Version 3 of the AWS SDK for PHP (Version 2 docs do not include the newest DynamoDB features, due to some technical limitations). You will need to use nested AttributeValueList parameters. You may also want to ask about this on the official DynamoDB forum.