title: DynamoDb batchGetItem and Partition Key and Sort Key
body: <p>I tried to use <code>batchGetItem</code> to return attributes of more then one item from a table but seems it works only with the combination of the partition key and range key, but what if I want to identify the requested items only by primary key ? is the only way is to create the table without the range key ?</p>
  
  <pre><code>    // Adding items
      $client-&gt;putItem(array(
          'TableName' =&gt; $table,
          'Item' =&gt; array(
              'id'     =&gt; array('S' =&gt; '2a49ab04b1534574e578a08b8f9d7441'),
              'name'   =&gt; array('S' =&gt; 'test1'),
              'user_name'   =&gt; array('S' =&gt; 'aaa.bbb')
          )
      ));
  
      // Adding items
      $client-&gt;putItem(array(
          'TableName' =&gt; $table,
          'Item' =&gt; array(
              'id'     =&gt; array('S' =&gt; '4fd70b72cc21fab4f745a6073326234d'),
              'name'   =&gt; array('S' =&gt; 'test2'),
              'user_name'   =&gt; array('S' =&gt; 'aaaa.bbbb'),
              'user_name1'   =&gt; array('S' =&gt; 'aaaaa.bbbbb')
          )
      ));
  
  $client-&gt;batchGetItem(array(
      "RequestItems" =&gt; array(
          $table =&gt; array(
              "Keys" =&gt; array(
                  // hash key
                  array(
                      "id"  =&gt; array( 'S' =&gt; "2a49ab04b1534574e578a08b8f9d7441"),
                  // range key
                      "name" =&gt; array( 'S' =&gt; "test1"),
                  ),
                  array(
                  // hash key
                      "id"  =&gt; array( 'S' =&gt; "4fd70b72cc21fab4f745a6073326234d"),
                  // range key
                      "name" =&gt; array( 'S' =&gt; "test2"),
                  ),
              )
          )
      )
  ));
  </code></pre>
  
  <p>As per the official documentation:</p>
  
  <p><a href="http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.Partitions.html" rel="noreferrer">http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.Partitions.html</a></p>
  
  <blockquote>
    <p>If the table has a composite primary key (partition key and sort key),
    DynamoDB calculates the hash value of the partition key in the same
    way as described in Data Distribution: Partition Key—but it stores all
    of the items with the same partition key value physically close
    together, ordered by sort key value.</p>
  </blockquote>
  
  <p>What are the advantages using <code>Partition Key and Sort Key</code> beside it stores all of the items with the same partition key value physically close together ?</p>
  
  <p>As per the official documentation:</p>
  
  <blockquote>
    <p>A single operation can retrieve up to 16 MB of data, which can contain
    as many as 100 items.  BatchGetItem will return a partial result if
    the response size limit is exceeded, the table's provisioned
    throughput is exceeded, or an internal processing failure occurs.</p>
  </blockquote>
  
  <p>How to handle the request if I need more then 100 items ? just loop through all the items from the code and request each time 100 times or there is another way to achieve it via the AWS SDK DynamoDB?</p>
  
  <p>Example of table creation:</p>
  
  <pre><code>$client-&gt;createTable(array(
          'TableName' =&gt; $table,
          'AttributeDefinitions' =&gt; array(
              array(
                  'AttributeName' =&gt; 'id',
                  'AttributeType' =&gt; 'N'      
              ),
              array(
                  'AttributeName' =&gt; 'name',
                  'AttributeType' =&gt; 'S'
              )
          ),
          'KeySchema' =&gt; array(
              array(
                  'AttributeName' =&gt; 'id',
                  'KeyType'       =&gt; 'HASH'
              ),
              array(
                  'AttributeName' =&gt; 'name',
                  'KeyType'       =&gt; 'RANGE'
              )
          ),
          'ProvisionedThroughput' =&gt; array(
              'ReadCapacityUnits'  =&gt; 5,
              'WriteCapacityUnits' =&gt; 5
          )
      ));
  </code></pre>
  
  <p>Thanks</p>
  
  <p><strong>UPDATE - Question to Mark B answer:</strong></p>
  
  <blockquote>
    <p>Yes you can create an index without a range key. The range key is
    entirely optional. However, even if you have a range key defined it is
    optional to include it in your query.  You can simply specify the hash
    key in your query to get all items with the hash key, which will be
    returned in an order based on the range key.</p>
  </blockquote>
  
  <p>If I specify only the hash key in my query on a table with hash key and range key, I getting the below error, if I specify only the hash key in my query on a table without range key it works. 
  Please note the table without index.</p>
  
  <pre><code>An uncaught Exception was encountered
  
  Type:        Aws\DynamoDb\Exception\DynamoDbException
  Message:     Error executing "BatchGetItem" on "https://dynamodb.eu-central-1.amazonaws.com"; AWS HTTP error: Client error: `POST https://dynamodb.eu-central-1.amazonaws.com` resulted in a `400 Bad Request` response:
  {"__type":"com.amazon.coral.validate#ValidationException","message":"The provided key element does not match the schema" (truncated...)
   ValidationException (client): The provided key element does not match the schema - {"__type":"com.amazon.coral.validate#ValidationException","message":"The provided key element does not match the schema"}
  Filename:    /var/app/vendor/aws/aws-sdk-php/src/WrappedHttpHandler.php
  </code></pre>