是否可以使用 DynamoDB 中的查询或扫描 API 对结果进行排序?
我需要知道 DynamoDB 是否有类似ORDER BY 'field'
SQL 查询的东西?
谢谢。
是否可以使用 DynamoDB 中的查询或扫描 API 对结果进行排序?
我需要知道 DynamoDB 是否有类似ORDER BY 'field'
SQL 查询的东西?
谢谢。
然而,没有明确说明,许多现实世界的用例显然需要排序,并且可以相应地通过哈希和范围类型主键进行建模:
在这种情况下,主键由两个属性组成。第一个属性是哈希属性,第二个是范围属性。Amazon DynamoDB 在散列主键属性上构建无序散列索引,在范围主键属性上构建排序范围索引。[强调我的]
然后,您可以使用此范围索引来选择性地通过Query API的RangeKeyCondition参数请求项目,并通过ScanIndexForward参数指定索引的前向或后向遍历(即排序方向)。
更新:您可以以相同的方式通过具有本地二级索引的属性进行排序。
您可以使用排序键并在查询中应用 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));
}
});
使用 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());
}
}
应该解决问题的另一种选择是
这将根据需要对表的任何值进行排序。这是一种非常有效的方式来查找表中排名最高的项目,而无需获取整个查询然后过滤它。
我从没想过这样一个微不足道的任务会变成 DynamoDB 中的问题。Dynamo 需要一些基本的分区。我设法通过添加一个额外的列状态来排序数据,然后使用这两个字段创建 GSI 索引。我通过 createdAt 字段订购了 status="active" 的数据。
创建 GSI
{
IndexName: "createdAt",
KeySchema: [
{ AttributeName: "status", KeyType: "HASH" },
{ AttributeName: "createdAt", KeyType: "RANGE" }
],
Projection: { ProjectionType: "ALL" },
ProvisionedThroughput: {
ReadCapacityUnits: N,
WriteCapacityUnits: N
}
}
查询数据
const result = await this.dynamoClient.query({
TableName: "my table",
IndexName: "createdAt",
KeyConditionExpression: "#status = :status and #createdAt > :createdAt",
Limit: 5,
ExpressionAttributeValues: {
":status": {
"S": "active"
},
":createdAt": {
"S": "2020-12-10T15:00:00.000Z"
}
},
ExpressionAttributeNames: {
"#status": "status",
"#createdAt": "createdAt"
},
});
如果您使用的是boto2并且您在表中的一列上有排序键,您可以通过说:
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 按排序键值逆序读取结果,然后将结果返回给客户端。
If the table already existed then add GSI (Global Secondary Index) to the attribute you want for the table and use Query, not Scan. If you are about to create the table then you can add LSI (Local Secondary Index) to the attribute you want.