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


83

DynamoDBのクエリまたはスキャンAPIを使用して結果を注文することは可能ですか?

DynamoDBにSQLクエリからの[ORDERBY 'フィールド']のようなものがあるかどうかを知る必要がありますか?

ありがとう。

回答:


42

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

この場合、主キーは2つの属性で構成されます。最初の属性はハッシュ属性で、2番目の属性は範囲属性です。Amazon DynamoDBは、ハッシュ主キー属性に順序付けされていないハッシュインデックスを作成し、範囲主キー属性に並べ替えられた範囲インデックスを作成します[私の強調]

その後、経由して、必要に応じて、要求項目に、この範囲のインデックスを使用することができますRangeKeyConditionのパラメータクエリAPIと指定し、前方または後方のインデックスのトラバースを経由して(つまり、ソート方向を)ScanIndexForwardのパラメータ。

更新:同じ方法で、ローカルセカンダリインデックスを持つ属性で並べ替えることができます。


18
ScanIndexForwardパラメータはクエリにのみ適用され、スキャンは正しくないようです。クエリを使用して、テーブル内のすべてのアイテムの順序付けられたページ付けされたリストを返すにはどうすればよいですか?スキャンは「*」を返す方法のようですが、結果を並べ替えるためのパラメーターがないようです。
case2000 2012

私はこの機能を使用していません。それについて読んだだけですが、クエリは制限の指定をサポートして、受信する結果の数を制限します。制限に達したときにクエリに一致するアイテムがさらにある場合は、LastEvaluatedKeyを受け取ります。これを使用して、別のクエリを実行し、結果を取得し続けることができます。
fernio 2014

1
重要な落とし穴:返された結果は実際にはソートされません。並べ替えは、「制限」値を適用した場合、またはアイテムの数が1MBのルックアップ制限を超えた場合にのみ機能します。たとえば、パーティションキー 'p1'とソートキー['b'、 'd'、 'a'、 'c'、 'e']の5つのレコードがあるとします。'p1'だけのクエリを実行すると、['b'、 'd'、 'a'、 'c'、 'e']を受け取ります。あなたは2の制限を指定した場合でも、それは[「A」、「B」]を返します
jameslol

29

並べ替えキーを使用し、クエリでScanIndexForwardパラメータを適用して、昇順または降順で並べ替えることができます。ここでは、返されるアイテムを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));
    }
});

8
問題は、すべてのアイテムを返品たい場合です。基本的に、これは、新しいダミー列を作成し、その列に同じ値をすべての行に割り当て、その列にGSIを作成し、スキャンの代わりにクエリを呼び出す必要があることを意味します。
JHH 2016年

キー以外のフィールドに基づいて戻りたい場合はどうなりますか?created_on番号フィールドのように
Yusuf

次に、すべてのレコードを取得してから、JavaScriptなどを使用してそれらをフィルタリングすることをお勧めします。DynamoDBは基本的に、機能が制限されたKey-Valueストアです。ただし、キーを使用できる場合は非常に高速です。
彗星

7

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());
    }
}

ScanIndexForwardを使用します(昇順の場合はtrue、降順の場合はfalse)
ABHAY JOHRI 2017

2

問題を解決する必要がある別のオプションは

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

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


上記は何ですか?ソートで生成されたIDに対して通常のハッシュが順序付けられていない場合、それを含めることは機能していないようです。私は何かが足りないのですか?
サマンサアトキンス

1

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

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

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

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

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


0

テーブルがすでに存在する場合は、テーブルに必要な属性にGSI(グローバルセカンダリインデックス)を追加し、スキャンではなくクエリを使用します。テーブルを作成しようとしている場合は、必要な属性にLSI(ローカルセカンダリインデックス)を追加できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.