title: DynamoDB: Query a secondary index with prefix (begins_with) only
body: <p>I want to a DynamoDB query for a string that's not a part of the primary key and I only have this string.</p>
  <p>As an example I have</p>
  <pre><code>Music
    Artist: String, PrimaryKey(HASH)
    SongTitle: String, PrimaryKey(RANGE)
    AlbumTitle: String, GlobalSecondaryKey(probably RANGE)
  </code></pre>
  <p>and I want to query &quot;all Music items that have AlbumTitle starts with 'Some'&quot;.</p>
  <p>I tried this with aws cli</p>
  <h2>create table (still with HASH for AlbumTitle)</h2>
  <pre class="lang-sh prettyprint-override"><code>aws dynamodb create-table \
      --table-name Music \
      --attribute-definitions \
          AttributeName=Artist,AttributeType=S \
          AttributeName=SongTitle,AttributeType=S \
          AttributeName=AlbumTitle,AttributeType=S \
      --key-schema \
          AttributeName=Artist,KeyType=HASH \
          AttributeName=SongTitle,KeyType=RANGE \
      --provisioned-throughput \
          ReadCapacityUnits=10,WriteCapacityUnits=5 \
      --global-secondary-indexes \
          &quot;[
              {
                  \&quot;IndexName\&quot;: \&quot;AlbumTitle-Index\&quot;,
                  \&quot;KeySchema\&quot;: [{\&quot;AttributeName\&quot;:\&quot;AlbumTitle\&quot;,\&quot;KeyType\&quot;:\&quot;HASH\&quot;}],
                  \&quot;Projection\&quot;:{ \&quot;ProjectionType\&quot;:\&quot;ALL\&quot; },
                  \&quot;ProvisionedThroughput\&quot;:{
                      \&quot;ReadCapacityUnits\&quot;: 1,
                      \&quot;WriteCapacityUnits\&quot;: 1
                  }
              }
          ]&quot;
  </code></pre>
  <p>wait until</p>
  <pre class="lang-sh prettyprint-override"><code>aws dynamodb describe-table --table-name Music | grep IndexStatus
  </code></pre>
  <p>responds</p>
  <pre><code> &quot;IndexStatus&quot;: &quot;ACTIVE&quot;, 
  </code></pre>
  <h2>put some items</h2>
  <pre class="lang-sh prettyprint-override"><code>aws dynamodb put-item \
      --table-name Music  \
      --item '{&quot;Artist&quot;: {&quot;S&quot;: &quot;No One You Know&quot;}, &quot;SongTitle&quot;: {&quot;S&quot;: &quot;Call Me Today&quot;}, &quot;AlbumTitle&quot;: {&quot;S&quot;: &quot;Somewhat Famous&quot;}, &quot;Awards&quot;: {&quot;N&quot;: &quot;1&quot;}}'
  aws dynamodb put-item \
      --table-name Music  \
      --item '{&quot;Artist&quot;: {&quot;S&quot;: &quot;No One You Know&quot;}, &quot;SongTitle&quot;: {&quot;S&quot;: &quot;Call Me Tomorrow&quot;}, &quot;AlbumTitle&quot;: {&quot;S&quot;: &quot;Something Famous&quot;}, &quot;Awards&quot;: {&quot;N&quot;: &quot;1&quot;}}'
  aws dynamodb put-item \
      --table-name Music \
      --item '{&quot;Artist&quot;: {&quot;S&quot;: &quot;Acme Band&quot;}, &quot;SongTitle&quot;: {&quot;S&quot;: &quot;Happy Day&quot;}, &quot;AlbumTitle&quot;: {&quot;S&quot;: &quot;Songs About Life&quot;}, &quot;Awards&quot;: {&quot;N&quot;: &quot;10&quot;} }'
  </code></pre>
  <h2>query with equal (works)</h2>
  <pre class="lang-sh prettyprint-override"><code>aws dynamodb query \
      --table-name Music \
      --index-name AlbumTitle-Index \
      --key-condition-expression &quot;AlbumTitle = :name&quot; \
      --expression-attribute-values '{&quot;:name&quot;:{&quot;S&quot;:&quot;Somewhat Famous&quot;}}'
  </code></pre>
  <h2>query with begins_with (does not work)</h2>
  <pre><code>aws dynamodb query \
      --table-name Music \
      --index-name AlbumTitle-Index \
      --key-condition-expression &quot;begins_with(AlbumTitle, :name)&quot; \
      --expression-attribute-values '{&quot;:name&quot;:{&quot;S&quot;:&quot;Some&quot;}}'
  
  </code></pre>
  <p>results in</p>
  <pre><code>An error occurred (ValidationException) when calling the Query operation: Query key condition not supported
  </code></pre>
  <p>Ok. That does not work, because I created the index <code>AlbumTitle-Index</code> with AlbumTitle(<strong>HASH</strong>). Hence I only can query equals.</p>
  <h2>problem / question</h2>
  <p>What do I need to change that I can perform a prefix search? I only find <code>begins_with</code> and everywhere it's combined with a HASH key as its first part. I don't have anything but the string that should be matched as a prefix in <code>AlbumTitle</code>.
  I cannot simply replace <code>HASH</code> with <code>RANGE</code> in the <code>AlbumTutle-Index</code> like</p>
  <pre><code>    --global-secondary-indexes \
          &quot;[
              {
                  \&quot;IndexName\&quot;: \&quot;AlbumTitle-Index\&quot;,
                  \&quot;KeySchema\&quot;: [{\&quot;AttributeName\&quot;:\&quot;AlbumTitle\&quot;,\&quot;KeyType\&quot;:\&quot;RANGE\&quot;}],
                  ...
  </code></pre>
  <p>because of</p>
  <pre><code>An error occurred (ValidationException) when calling the CreateTable operation: Invalid KeySchema: The first KeySchemaElement is not a HASH key type
  </code></pre>