web-dev-qa-db-ja.com

DynamoDBでクエリまたはスキャンを使用して結果を並べ替えることは可能ですか?

DynamoDBのクエリまたはスキャンAPIで結果を並べ替えることは可能ですか?

DynamoDBにSQLクエリからの[ORDER BY 'field']のようなものがあるかどうかを知る必要がありますか?

ありがとう。

64
Samuel Negru

ただし、明示的にではありませんが、多くの実世界のユースケースでは順序付けが明らかに必要であり、それに応じて ハッシュおよび範囲タイプの主キー によってモデル化できます。

この場合、主キーは2つの属性で構成されます。最初の属性はハッシュ属性で、2番目の属性は範囲属性です。 Amazon DynamoDBは、ハッシュプライマリキー属性に順序付けられていないハッシュインデックスを作成し、範囲プライマリキー属性にソート範囲インデックスを作成します[emphasis mine]

次に、この範囲インデックスを使用して、オプションで Query APIRangeKeyConditionパラメータを介してアイテムをリクエストし、インデックスの前方または後方トラバーサル(つまり、ソート方向)ScanIndexForwardパラメーター経由。

更新:同様に ローカルセカンダリインデックス を使用して属性で並べ替えることができます。

38
Steffen Opel

Sort-keyを使用し、ScanIndexForwardパラメーターを query で適用して、昇順または降順でソートできます。ここでは、返されるアイテムを1に制限します。

var params = {
    TableName: 'Events',
    KeyConditionExpression: 'Organizer = :organizer',
    Limit: 1,
    ScanIndexForward: false,    // true = ascending, false = descending
    ExpressionAttributeValues: {
        ':organizer': organizer
    }
};

docClient.query(params, function(err, data) {
    if (err) {
        console.log(JSON.stringify(err, null, 2));
    } else {
        console.log(JSON.stringify(data, null, 2));
    }
});
18
kometen

ScanIndexForward(昇順の場合はtrue、降順の場合はfalse)を使用し、クエリ式のsetLimit値を使用して結果を制限することもできます。

単一のレコードを見つけるためにQueryPageを使用したコードを以下で見つけてください。

public void fetchLatestEvents() {
    EventLogEntitySave entity = new EventLogEntitySave();
    entity.setId("1C6RR7JM0JS100037_contentManagementActionComplete");

    DynamoDBQueryExpression<EventLogEntitySave> queryExpression = new DynamoDBQueryExpression<EventLogEntitySave>().withHashKeyValues(entity);
    queryExpression.setScanIndexForward(false);
    queryExpression.withLimit(1);
    queryExpression.setLimit(1);

    List<EventLogEntitySave> result = dynamoDBMapper.queryPage(EventLogEntitySave.class, queryExpression).getResults();
    System.out.println("size of records = "+result.size() );
}

@DynamoDBTable(tableName = "PROD_EA_Test")
public class EventLogEntitySave {

        @DynamoDBHashKey
        private String id;
        private String reconciliationProcessId;
        private String vin;
        private String source;
}

public class DynamoDBConfig {
    @Bean
    public AmazonDynamoDB amazonDynamoDB() {

            String accesskey = "";
            String secretkey = "";
            //
            // creating dynamo client
            BasicAWSCredentials credentials = new BasicAWSCredentials(accesskey, secretkey);
            AmazonDynamoDB dynamo = new AmazonDynamoDBClient(credentials);
            dynamo.setRegion(Region.getRegion(Regions.US_WEST_2));
            return dynamo;
        }

    @Bean
    public DynamoDBMapper dynamoDBMapper() {
        return new DynamoDBMapper(amazonDynamoDB());
    }
}
6
ABHAY JOHRI

boto2を使用しており、テーブルの列の1つにソートキーがある場合、次のように言うことで、取得したものを順番または逆順に並べ替えることができます。

result = users.query_2(
    account_type__eq='standard_user',
    reverse=True)

botoを使用しており、結果を並べ替える列に並べ替えキーがある場合、次のように言って取得するデータを並べ替えることができます。

result = users.query(
    KeyConditionExpression=Key('account_type').eq('standard_user'),
    ScanIndexForward=True)

Boto3では、ScanIndexForwardがtrueの場合、DynamoDBは、格納された順序で(ソートキー値によって)結果を返します。これがデフォルトの動作です。 ScanIndexForwardがfalseの場合、DynamoDBはソートキー値の逆順で結果を読み取り、結果をクライアントに返します。

1
pilatipus

問題を解決する別のオプションは

  1. 「通常の」ハッシュキーを使用して、ローカルのセカンダリインデックスをLSIのハッシュキーにも定義します。
  2. ソートするフィールドをLSIの「ソートキー」として定義します
  3. LSIにクエリを実行し、必要に応じて順序を設定します(上記を参照)

これにより、必要に応じてテーブルの値を並べ替えることができます。クエリ全体を取得し、後でフィルタリングすることなく、テーブル内で最高ランクのアイテムを見つけるための非常に効率的な方法です。

1
Geole