PHP
AWS
DynamoDB

DynamoDBで件数だけ取得するサンプル

概要

DynamoDBのデータの件数を数えるとき、scanやqueryで検索した結果をプログラムで数えると件数が多いときに遅くなってしまう。selectオプションを使用することにより件数のみ早く取得することが可能。

PHP

準備

  • aws.pharをダウンロード

https://github.com/aws/aws-sdk-php/releases

今回(2017/08/04)のバージョンは、Version 3.32.3

サンプル

下記を設定する。

  • REGION
  • KEY
  • SECRET
  • TABLE NAME
  • INDEX NAME(必要な場合)
  • SEARCH KEY 検索するキー
  • SERCH VALUE 検索する値

aws.pharと同じディレクトリに置いた。

dynamo_count.php
<?php

require_once('aws.phar');

use Aws\DynamoDb\DynamoDbClient;
use Aws\DynamoDb\Exception\DynamoDbException;

$client = new DynamoDbClient(array(
  'version' => 'latest',
  'region'  => '<REGION>',
  'credentials' => [
    'key'     => '<KEY>',
    'secret'  => '<SECRET>',
  ]
));

$result_count = 0;
$LastEvaluatedKey = null;

do {
  $arg = array(
    'TableName' => '<TABLE NAME>',
    'Select' => 'COUNT',
    'ScanIndexForward' => false,
    'IndexName' => '<INDEX NAME>', // 必要な場合のみ
    'KeyConditions' => array(
      '<SEARCH KEY>' => array(
        'AttributeValueList' => array(
          array('S'=>'<SEARCH VALUE>') // Sの場合
        ),
        'ComparisonOperator' => 'EQ'
      ),
    ),
  );

  if($LastEvaluatedKey){
    $arg['ExclusiveStartKey'] = $LastEvaluatedKey;
  }

  $result = $client->query($arg);

  $result_count = $result_count + $result['Count'];
  $LastEvaluatedKey = $result['LastEvaluatedKey'];

} while ($LastEvaluatedKey);

print_r($result_count);

結果は1MB制限があるので、ExclusiveStartKeyを指定して繰り返して取らないと正しい値が取れない。

実行

$ php dynamo_count.php

Scanの場合

scanの時は、下記の部分を変更

$arg = array(
    'TableName' => '<TABLE NAME>',
    'Select' => 'COUNT',
    'ScanIndexForward' => false,
  );
$result = $client->scan($arg);

AWS CLI

上記のオプションとちょっと違うけどメモ的に書いておく。

$ aws dynamodb --profile <PROFILE> query --table-name <TABLE NAME> --key-condition-expression "#key = :key" --expression-attribute-names '{"#key": "<SEARCH KEY>"}' --expression-attribute-values '{":key": {"S":"<SEARCH VALUE>"}}' --index-name <INDEX NAME> --select COUNT
$ aws dynamodb --profile <PROFILE> scan --table-name <TABLE NAME> --select COUNT

こんなのが返ってきます。

{
    "Count": <件数>,
    "ScannedCount": <件数>,
    "ConsumedCapacity": null
}