Reputation: 2030
I must be missing something simple here. The goal of this test is to set a new element in an existing Map. The following PHP test function works fine to update the item, but instead of setting the person attribute's (a Map) middle initial value to "T", it creates a new top level attribute called "person.mi" and sets it to "T".
The docs for Document Paths specify dot notation for accessing Map elements, so....I don't know what I am missing.
public function Z() {
$ddb = DynamoDbClient::factory(array('region' => 'us-east-1')); // EC2 role security
try {
$response = $ddb->updateItem(array(
"TableName" => "test",
"Key" => array("id" => array("N" => 1)),
"UpdateExpression" => "SET #fieldName = :value",
"ExpressionAttributeNames" => array("#fieldName" => "person.mi"),
"ExpressionAttributeValues" => array(":value" => array("S" => "T"))
));
} catch (Exception $e) {
throw new DDBException("Call to TestDDB->Z failed: " . $e->getMessage());
}
}
Anyone see where I am going wrong? Thanks.
Upvotes: 5
Views: 6547
Reputation: 1638
Even after reading the documentation, I had trouble with this case. Here is an actual code sample:
public function Z() {
$ddb = DynamoDbClient::factory(array('region' => 'us-east-1')); // EC2 role security
try {
$response = $ddb->updateItem(array(
"TableName" => "test",
"Key" => array("id" => array("N" => 1)),
"UpdateExpression" => "SET #fieldName.mi = :value",
"ExpressionAttributeNames" => array("#fieldName" => "person"),
"ExpressionAttributeValues" => array(":value" => array("S" => "T"))
));
} catch (Exception $e) {
throw new DDBException("Call to TestDDB->Z failed: " . $e->getMessage());
}
}
The difference between the original code and mine is in the UpdateExpression and ExpressionAttributeNames only.
Note that while I am using a placeholder for person, I am not using a placeholder for mi.
Upvotes: 0
Reputation: 47319
That is because the dot is thought to be a part of the attribute name. You should use 2 expression attribute names. From the documentation:
But what if you decided to use an expression attribute name instead? For example, what would happen if you were to define
#mmmk
as a substitute forMyMap.MyKey
? DynamoDB would return an empty result, instead of the expected string. This is because DynamoDB interprets a dot in an expression attribute value as a character within an attribute's name. When DynamoDB evaluates the expression attribute name#mmmk
, it determines thatMyMap.MyKey
refers to a scalar attribute—which is not what was intended.The correct approach would be to define two expression attribute names, one for each element in the document path:
#mm — MyMap
#mk — MyKey
You could then use the following projection expression:
#mm.#mk
Upvotes: 2