Можно ли ЗАКАЗАТЬ результаты с помощью API запросов или сканирования в DynamoDB?
Мне нужно знать, есть ли в DynamoDB что-то вроде [ORDER BY 'field'] из запросов SQL?
Благодарю.
Можно ли ЗАКАЗАТЬ результаты с помощью API запросов или сканирования в DynamoDB?
Мне нужно знать, есть ли в DynamoDB что-то вроде [ORDER BY 'field'] из запросов SQL?
Благодарю.
Ответы:
Однако неявно, порядок, очевидно, необходим для многих реальных случаев использования и может быть смоделирован с помощью первичного ключа типа хэша и диапазона соответственно:
В этом случае первичный ключ состоит из двух атрибутов. Первый атрибут - это хэш-атрибут, а второй - атрибут диапазона. Amazon DynamoDB строит неупорядоченный хэш-индекс по атрибуту первичного ключа хэша и отсортированный индекс диапазона по атрибуту первичного ключа диапазона . [курсив мой]
Затем вы можете использовать этот индекс диапазона для необязательного запроса элементов через параметр RangeKeyCondition API запросов и указать прямой или обратный обход индекса (т. Е. Направление сортировки) через параметр 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 в Query Expression.
Ниже приведен код, в котором 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());
}
}
Другой вариант, который должен решить проблему, - это
Это позволит отсортировать любое значение вашей таблицы по мере необходимости. Это очень эффективный способ найти элементы с наивысшим рейтингом в вашей таблице без необходимости получать весь запрос и затем фильтровать его.
Если вы используете 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)
Помните, что в boto3, если ScanIndexForward имеет значение true, DynamoDB возвращает результаты в том порядке, в котором они хранятся (по значению ключа сортировки). Это поведение по умолчанию. Если ScanIndexForward имеет значение false, DynamoDB считывает результаты в обратном порядке по значению ключа сортировки, а затем возвращает результаты клиенту.
Если таблица уже существует, добавьте GSI (глобальный вторичный индекс) к атрибуту, который вы хотите для таблицы, и используйте запрос, а не сканирование. Если вы собираетесь создать таблицу, вы можете добавить LSI (локальный вторичный индекс) к нужному атрибуту.
Никогда не думал, что такая банальная задача может превратиться в проблему в DynamoDB. Динамо требует некоторой базовой перегородки. Мне удалось упорядочить данные, добавив дополнительный статус столбца , а затем создать индекс GSI с использованием обоих полей. Я заказываю данные со статусом status = "active" по полю 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"
},
});