Amazon dynamodb 是否可以在DynamoDB中通过查询或扫描对结果进行排序?
是否可以在DynamoDB中使用查询或扫描API对结果进行排序 我需要知道DynamoDB是否有类似于SQL查询中按“字段”排序的Amazon dynamodb 是否可以在DynamoDB中通过查询或扫描对结果进行排序?,amazon-dynamodb,Amazon Dynamodb,是否可以在DynamoDB中使用查询或扫描API对结果进行排序 我需要知道DynamoDB是否有类似于SQL查询中按“字段”排序的 谢谢。不过,对于许多真实世界的用例来说,排序显然是必需的,并且可以通过相应的方式进行建模: 在这种情况下,主键由两个属性组成。第一 属性是散列属性,第二个是范围 属性AmazonDynamodb在散列上构建一个无序散列索引 主键属性和主范围上的排序范围索引 键属性。[我的重点] 然后,您可以使用此范围索引通过的RangeKeyCondition参数选择性地请求项目,
谢谢。不过,对于许多真实世界的用例来说,排序显然是必需的,并且可以通过相应的方式进行建模: 在这种情况下,主键由两个属性组成。第一 属性是散列属性,第二个是范围 属性AmazonDynamodb在散列上构建一个无序散列索引 主键属性和主范围上的排序范围索引 键属性。[我的重点] 然后,您可以使用此范围索引通过的RangeKeyCondition参数选择性地请求项目,并通过ScanIndexForward参数指定索引的向前或向后遍历(即排序方向)
更新:您可以按具有的属性按相同方式排序。您可以使用排序键并在a中应用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));
}
});
如果您使用的是boto2,并且表中的一列上有排序键,则可以按顺序或相反顺序对检索的内容进行排序,方法是:
result = users.query_2(
account_type__eq='standard_user',
reverse=True)
result = users.query(
KeyConditionExpression=Key('account_type').eq('standard_user'),
ScanIndexForward=True)
如果您使用的是boto3,并且您希望对结果进行排序的列上有排序键,您可以对检索到的数据进行排序,方法是:
result = users.query_2(
account_type__eq='standard_user',
reverse=True)
result = users.query(
KeyConditionExpression=Key('account_type').eq('standard_user'),
ScanIndexForward=True)
请记住,在boto3中,如果ScanIndexForward为true,DynamoDB将按存储顺序(按排序键值)返回结果。这是默认行为。如果ScanIndexForward为false,DynamoDB将按排序键值的相反顺序读取结果,然后将结果返回给客户端。使用ScanIndexForward(true表示升序,false表示降序),还可以使用查询表达式的setLimit值限制结果
请在下面查找用于查找单个记录的查询页面的代码
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());
}
}
public void fetchLatestEvents(){
EventLogEntitySave实体=新建EventLogEntitySave();
entity.setId(“1C6RR7JM0JS100037_contentManagementActionComplete”);
DynamoDBQueryExpression queryExpression=新的DynamoDBQueryExpression(),带有HashKeyValues(实体);
queryExpression.setScanIndexForward(false);
queryExpression.withLimit(1);
queryExpression.setLimit(1);
List result=dynamoDBMapper.queryPage(EventLogEntitySave.class,queryExpression).getResults();
System.out.println(“记录大小=“+result.size());
}
@发电机表(tableName=“生产测试”)
公共类EventLogEntitySave{
@发电机钥匙
私有字符串id;
私有字符串对账过程ID;
私有字符串vin;
私有字符串源;
}
公共类DynamoDBConfig{
@豆子
公共AmazonDynamoDB AmazonDynamoDB(){
字符串accesskey=“”;
字符串secretkey=“”;
//
//创建dynamo客户端
BasicAWSCredentials credentials=新的BasicAWSCredentials(accesskey、secretkey);
AmazonDynamoDB dynamo=新的AmazonDynamoDBClient(凭证);
dynamo.setRegion(Region.getRegion(Regions.US_WEST_2));
回程发电机;
}
@豆子
公共DynamoDBMapper DynamoDBMapper(){
返回新的DynamoDBMapper(amazonDynamoDB());
}
}
解决此问题的另一个方法是
这将根据需要对表中的任何值进行排序。这是一种非常有效的方法,可以在表中查找排名最高的项,而无需获取整个查询,然后对其进行过滤。如果表已经存在,则将GSI(全局二级索引)添加到表的属性中,并使用查询,而不是扫描。如果您即将创建表,那么您可以将LSI(本地二级索引)添加到所需的属性。我从未想过,这样一项琐碎的任务会在DynamoDB中变成问题。发电机需要一些基本的分区。我通过添加一个额外的列状态来对数据进行排序,然后使用这两个字段创建GSI索引。我通过createdAt字段订购状态为“活动”的数据 创建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"
},
});
ScanIndexForward参数似乎仅适用于,不正确?如何使用查询返回表中所有项的有序分页列表?扫描似乎是返回“*”的方式,但它似乎没有用于排序结果的参数。我没有使用此功能,只是了解了它,但查询支持指定一个,以限制收到的结果的数量,如果达到限制时有更多项与您的查询相匹配,您将收到一个LastEvaluatedKey,可用于执行另一个查询并继续检索结果。重要提示:返回的结果实际上不会被排序。只有在应用“限制”值或项目数超过1MB查找限制时,排序才会起作用。例如,您可能有5条记录,分区键为'p1',排序键为:['b','d','a','c','E']。如果只对“p1”执行查询,您将收到['b','d','a','c','e']。但如果您指定限制为2,它将返回['b','a'],问题是您是否要返回所有项目。从本质上说,这意味着您必须创建一个新的伪列,将其中的相同值分配给所有行,在该列上创建一个GSI,并调用查询而不是扫描。如果我想基于某个非键字段返回,该怎么办?就像在数字字段上创建_一样,您可能希望获取所有记录,然后使用javascript或类似的方法过滤这些记录。DynamoDB基本上是一个功能有限的键值存储。但是速度非常快