Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to ORDER results with query or scan in DynamoDB?

Is it possible to ORDER results with Query or Scan API in DynamoDB?

I need to know if DynamoDB has something like ORDER BY 'field' from SQL queries?

Thanks.

like image 202
Samuel Negru Avatar asked Feb 15 '12 16:02

Samuel Negru


People also ask

How do I sort DynamoDB query results?

Query results are always sorted by the sort key value. If the data type of the sort key is Number, the results are returned in numeric order; otherwise, the results are returned in order of UTF-8 bytes. By default, the sort order is ascending. To reverse the order, set the ScanIndexForward parameter to false.

What is the difference between Scan and query in DynamoDB?

DynamoDB supports two types of read operations: Query and Scan. To find information, a query operation uses either the primary key or the index key. Scan, as the name implies, is a read call that scans the entire table for a specified result. DynamoDB is designed to be query-optimized.

Does DynamoDB support sorting?

DynamoDB uses the partition key as an input to the hash function. The hash function's output decides which partition the item will be placed in, and all items with the same partition key value are stored together. The sort key is used to sort and order items in a partition.

What does the query operation in Amazon DynamoDB allow you to do?

The Query operation allows you to limit the number of items that it reads. To do this, set the Limit parameter to the maximum number of items that you want. For example, suppose that you Query a table, with a Limit value of 6 , and without a filter expression.


4 Answers

Not explicitly, however, ordering is obviously needed for many real world use cases and can be modeled by means of the Hash and Range Type Primary Key accordingly:

In this case, the primary key is made of two attributes. The first attributes is the hash attribute and the second one is the range attribute. Amazon DynamoDB builds an unordered hash index on the hash primary key attribute and a sorted range index on the range primary key attribute. [emphasis mine]

You can then use this range index to optionally request items via the RangeKeyCondition parameter of the Query API and specify forward or backward traversal of the index (i.e. the sort direction) via the ScanIndexForward parameter.

Update: You can order by an attribute with a local secondary index in the same way.

like image 151
Steffen Opel Avatar answered Oct 10 '22 20:10

Steffen Opel


You can use the sort-key and apply the ScanIndexForward parameter in a query to sort in either ascending or descending order. Here I limit items returned to 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));
    }
});
like image 29
kometen Avatar answered Oct 10 '22 20:10

kometen


Use ScanIndexForward(true for ascending and false for descending) and can also limit the result using setLimit value of Query Expression.

Please find below the code where used QueryPage for finding the single record.

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());
    }
}
like image 8
ABHAY JOHRI Avatar answered Oct 10 '22 18:10

ABHAY JOHRI


Another option which should solve the problem is to

  1. Define a local secondary index with the "normal" hash key to be the hash key of the LSI as well
  2. Define the field you want to sort as "Sort Key" of the LSI
  3. Query the LSI and set the ordering as desired (see above)

This will enable sorting of any value of your table as required. It is a very efficient way to find the highest ranking items in your table without the need to get the whole query and then filtering it afterwards.

like image 2
Geole Avatar answered Oct 10 '22 20:10

Geole