DynamoDB에서 항목 수를 가져 오는 방법은 무엇입니까?


84

DynamoDB 쿼리로 항목 수를 알고 싶습니다.

DynamoDB를 쿼리 할 수 ​​있지만 '총 항목 수'만 알고 싶습니다.

예를 들어, MySQL의 'SELECT COUNT (*) FROM ... WHERE ...'

$result = $aws->query(array(
 'TableName' => 'game_table',
 'IndexName' => 'week-point-index',
 'KeyConditions' => array(
    'week' => array(
        'ComparisonOperator' => 'EQ',
        'AttributeValueList' => array(
            array(Type::STRING => $week)
        )
    ),
    'point' => array(
        'ComparisonOperator' => 'GE',
        'AttributeValueList' => array(
            array(Type::NUMBER => $my_point)
        )
    )
 ),
));
echo Count($result['Items']);

이 코드는 내 포인트보다 높은 모든 사용자 데이터를 가져옵니다.

$ result 수가 100,000이면 $ result가 너무 큽니다. 그리고 그것은 쿼리 크기의 한계를 초과합니다.

도움이 필요합니다.

답변:


29

Select매개 변수를 사용COUNT 하고 요청에 사용할 수 있습니다 . "일치하는 항목 자체가 아니라 일치하는 항목의 수를 반환합니다". 중요 , 자라 같은 코멘트에 Saumitra R. Bhave에 의해 , 쿼리 결과 집합의 크기가 1 MB보다 큰이가 "다음 ScannedCount 및 개수는 전체 항목의 부분적인 수를 나타냅니다. 여러를 수행해야합니다 모든 결과를 검색하기위한 쿼리 작업 " .

저는 PHP에 익숙하지 않지만 여기에 Java와 함께 사용할 수있는 방법이 있습니다. 그런 다음 Count(내가 PHP의 함수라고 추측하는) 사용 하는 대신 응답'Items'Count값을 사용할 수 있습니다 - $result['Count']:

final String week = "whatever";
final Integer myPoint = 1337;
Condition weekCondition = new Condition()
        .withComparisonOperator(ComparisonOperator.EQ)
        .withAttributeValueList(new AttributeValue().withS(week));
Condition myPointCondition = new Condition()
        .withComparisonOperator(ComparisonOperator.GE)
        .withAttributeValueList(new AttributeValue().withN(myPoint.toString()))

Map<String, Condition> keyConditions = new HashMap<>();
keyConditions.put("week", weekCondition);
keyConditions.put("point", myPointCondition);

QueryRequest request = new QueryRequest("game_table");
request.setIndexName("week-point-index");
request.setSelect(Select.COUNT);
request.setKeyConditions(keyConditions);

QueryResult result = dynamoDBClient.query(request);
Integer count = result.getCount();

WHERE절 을 에뮬레이션 할 필요가없는 경우 DescribeTable요청을 사용하고 결과 항목 수를 사용하여 추정치를 얻을 수 있습니다.

지정된 테이블의 항목 수입니다. DynamoDB는이 값을 약 6 시간마다 업데이트합니다. 최근 변경 사항은이 값에 반영되지 않을 수 있습니다.

또한 Saumitra R. Bhave 가이 답변에 대한 의견에 언급 한 문서 의 중요한 참고 사항 :

크기의 경우 Query결과 세트는 1 MB보다 큰이며, ScannedCount그리고 Count전체 항목 중 일부만 카운트를 나타낸다. Query모든 결과를 검색하려면 여러 작업 을 수행해야합니다 ( 테이블 쿼리 결과 페이지 매기기 참조 ).


17
docs.aws.amazon.com/amazondynamodb/latest/developerguide/…에 따라 여기에 작은 문제가 있다고 생각합니다. "쿼리 결과 집합의 크기가 1MB보다 크면 ScannedCount 및 Count가 전체 항목의 일부만 계산합니다. "라는 말은 기본적으로 항목을 먼저 가져온 다음 계산한다는 의미이며, 가져온 항목의 크기가 1MB를 초과하면 '개수'도 페이지가 매겨집니다
Saumitra R. Bhave

나는 mkobit의 원작 @ 도용하고 싶지 않아,하지만이 유창 체인을 사용하여 할 수있는 방법입니다 :AmazonDynamoDBClientBuilder.standard().withRegion(region).withCredentials(credentialsProvider).build() .query(new QueryRequest(freeKeysTableName).withSelect(Select.COUNT)).getCount()
스리 Sarnobat

2
답변을 완료하려면 LastEvaluatedKey가 더 이상 결과에 나타나지 않을 때까지 호출을 반복해야 할 수 있으며 다음과 같을 수 있습니다 (위 코드의 끝 부분에 있음). while(result.getLastEvaluatedKey()!=null){ request.setExclusiveStartKey(result.getLastEvaluatedKey()); result = dynamoDBClient.query(request); count+= result.getCount(); }
Peter Koncz

141

으로 AWS DynamoDB의 CLI 당신은을 통해 그것을 얻을 수 스캔 은 다음과 같습니다 :

aws dynamodb scan --table-name <TABLE_NAME> --select "COUNT"

응답은 다음과 유사합니다.

{
    "Count": 123,
    "ScannedCount": 123,
    "ConsumedCapacity": null
}

이 정보는 describe-table api 와는 달리 실시간입니다.


2
@JHH 방금 이것을 시도했으며 읽기 용량 단위를 사용하는 것으로 보입니다. DynamoDB 콘솔에 따르면 내 쿼리는 약 12 ​​개 단위를 소비했습니다 (1 개만 구성됨). 쿼리를 처리하기 위해 버스트 용량을 사용하고 있다고 가정합니다.
Zodman

2
@Zodman 시도해 주셔서 감사합니다! 문서를 한 번 더 읽어 보니 이전에 놓친 개수에 대한 진술을 발견했습니다. "DynamoDB가 각 항목을 읽어야하기 때문에 항목 개수를 가져 오는 것은 동일한 양의 읽기 용량 단위를 사용하며 동일한 항목 크기 계산을 따릅니다. 항목 수를 늘리기 위해. " docs.aws.amazon.com/amazondynamodb/latest/developerguide/…
JHH

2
적어도 최종적으로 일관된 경계 내에서 카운트를 캐싱하는 것이 하나의 CU 만 사용하도록하는 것이 가능하다고 생각할 수 있지만 카운트 만 얻는 것은 그리 일반적인 시나리오가 아닐 수 있습니다.
JHH

2
@HelenNeely 예,이 방법은 최신 항목 수를 제공합니다.
Daniel Bubenheim

1
이 대답은 적어도 질문의 맥락에서 정확하지 않습니다. 문제는 필터 표현식과 일치하는 레코드 수를 가져 오는 방법이므로 WHERE 문과 비교합니다. AFAIK는 몇 달 동안 이것을 알아 내려고 시도한 결과 일치하는 레코드 수를 얻을 수 없습니다. dynamoDB는 테이블 또는 인덱스의 각 레코드를 살펴보고 필터와 일치하는 레코드를 한 번에 1000 개의 레코드로 반환합니다. 일치하는 레코드는 20 개만있을 수 있으며 개수로 20 개를 얻을 수 있습니다. 그러나 다음 1000 개의 레코드에는 40 개가있을 수 있습니다.
Chris Love

22

UI에서도 볼 수 있습니다. 테이블의 개요 탭으로 이동하면 항목 수를 볼 수 있습니다. 누군가에게 도움이되기를 바랍니다.


6
예,하지만 여기에는 제한이 있습니다. "저장소 크기와 항목 수는 실시간으로 업데이트되지 않습니다. 대략 6 시간마다 정기적으로 업데이트됩니다."
matthias

또한 쿼리 수를 확인하려면 개요 탭에서 수행 할 수 없습니다. 내 쿼리의 결과 집합 수가 아니라 테이블의 총 행만 표시됩니다.
Jyotsana Nandwani 2019

7

테이블 이름을 바꾸고 아래 쿼리를 사용하여 로컬 환경에서 데이터를 가져옵니다.

aws dynamodb scan --table-name <TABLE_NAME> --select "COUNT" --endpoint-url http://localhost:8000

테이블 이름을 바꾸고 엔드 포인트 URL을 제거하여 프로덕션 환경에서 데이터를 가져옵니다.

aws dynamodb scan --table-name <TABLE_NAME> --select "COUNT"

6

여기에 도달하고 C #으로 작업하는 경우 코드는 다음과 같습니다.

var cancellationToken = new CancellationToken();

var request = new ScanRequest("TableName") {Select = Select.COUNT};

var result = context.Client.ScanAsync(request, cancellationToken).Result;

totalCount = result.Count;

항목이 1MB 이상인 경우 작동하지 않습니다.
JohnOpincar

1

PHP의 Java와 유사하게 'COUNT'값으로 PARAMETER를 선택하십시오.

$result = $aws->query(array(
 'TableName' => 'game_table',
 'IndexName' => 'week-point-index',
 'KeyConditions' => array(
    'week' => array(
        'ComparisonOperator' => 'EQ',
        'AttributeValueList' => array(
            array(Type::STRING => $week)
        )
    ),
    'point' => array(
        'ComparisonOperator' => 'GE',
        'AttributeValueList' => array(
            array(Type::NUMBER => $my_point)
        )
    )
 ),
 'Select' => 'COUNT'
));

다음과 같이 액세스합니다.

echo $ result [ '개수'];

로하지만 Saumitra는 위에서 언급 한 것이 마지막 업데이트 카운트 값을 얻을 널 (null)을 반환 때까지 그 경우 사용 LastEvaluatedKey에 1 MB보다 결과 집합의 largers에주의.



0
len(response['Items'])

필터링 된 행의 개수를 제공합니다.

어디,

fe = Key('entity').eq('tesla')
response = table.scan(FilterExpression=fe)

0

나는 스캔 대신 쿼리를 사용하는 것을 보여주는 완전히 기능적이고 잘 테스트 된 답변을 원하는 C #을 사용하는 모든 사람을 위해이 답변을 게시하고 있습니다. 특히이 답변은 1MB 이상의 항목 크기를 처리합니다.

        public async Task<int> GetAvailableCount(string pool_type, string pool_key)
    {
        var queryRequest = new QueryRequest
        {
            TableName = PoolsDb.TableName,
            ConsistentRead = true,
            Select = Select.COUNT,
            KeyConditionExpression = "pool_type_plus_pool_key = :type_plus_key",
            ExpressionAttributeValues = new Dictionary<string, AttributeValue> {
                {":type_plus_key", new AttributeValue { S =  pool_type + pool_key }}
            },
        };
        var t0 = DateTime.UtcNow;
        var result = await Client.QueryAsync(queryRequest);
        var count = result.Count;
        var iter = 0;
        while ( result.LastEvaluatedKey != null && result.LastEvaluatedKey.Values.Count > 0) 
        {
            iter++;
            var lastkey = result.LastEvaluatedKey.Values.ToList()[0].S;
            _logger.LogDebug($"GetAvailableCount {pool_type}-{pool_key} iteration {iter} instance key {lastkey}");
            queryRequest.ExclusiveStartKey = result.LastEvaluatedKey;
            result = await Client.QueryAsync(queryRequest);
            count += result.Count;
        }
        _logger.LogDebug($"GetAvailableCount {pool_type}-{pool_key} returned {count} after {iter} iterations in {(DateTime.UtcNow - t0).TotalMilliseconds} ms.");
        return count;
    }
}

-1

Scala에서 :

import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder
import com.amazonaws.services.dynamodbv2.document.DynamoDB
val client = AmazonDynamoDBClientBuilder.standard().build()

val dynamoDB = new DynamoDB(client)
val tableDescription = dynamoDB.getTable("table name").describe().getItemCount()

-2

필요한 tableName의 총 개수를 얻기 위해 스캔을 사용했습니다. 다음은 동일한 Java 코드 스 니펫입니다.

Long totalItemCount = 0;
do{
    ScanRequest req = new ScanRequest();
    req.setTableName(tableName);

    if(result != null){
        req.setExclusiveStartKey(result.getLastEvaluatedKey());
    }

    result = client.scan(req);

    totalItemCount += result.getItems().size();

} while(result.getLastEvaluatedKey() != null);

System.out.println("Result size: " + totalItemCount);

-5

이것은 AWS JavaScript SDK 사용자를위한 솔루션이며 다른 언어에서도 거의 동일합니다.

Result.data.Count는 원하는 정보를 제공합니다.

 apigClient.getitemPost({}, body, {})

    .then(function(result){

        var dataoutput = result.data.Items[0];

        console.log(result.data.Count);
  }).catch( function(result){

});

2
답변에 설명을 포함하십시오.
WonderWorker
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.