Czy można ZAMAWIAĆ wyniki za pomocą interfejsu API zapytań lub skanowania w DynamoDB?
Muszę wiedzieć, czy DynamoDB ma coś takiego jak [ORDER BY „pole”] z zapytań SQL?
Dzięki.
Czy można ZAMAWIAĆ wyniki za pomocą interfejsu API zapytań lub skanowania w DynamoDB?
Muszę wiedzieć, czy DynamoDB ma coś takiego jak [ORDER BY „pole”] z zapytań SQL?
Dzięki.
Odpowiedzi:
Jednak nie jest to jednoznaczne, kolejność jest oczywiście potrzebna w wielu przypadkach użycia w świecie rzeczywistym i może być odpowiednio modelowana za pomocą klucza podstawowego typu Hash i Range Type :
W tym przypadku klucz podstawowy składa się z dwóch atrybutów. Pierwszy atrybut to atrybut hash, a drugi to atrybut range. Amazon DynamoDB buduje nieuporządkowany indeks skrótu na podstawie atrybutu klucza podstawowego skrótu i posortowany indeks zakresu na atrybucie klucza podstawowego zakresu . [podkreślenie moje]
Następnie można użyć tego indeksu zakresu, aby opcjonalnie zażądać elementów za pośrednictwem parametru RangeKeyCondition interfejsu API Query i określić przechodzenie indeksu w przód lub w tył (tj. Kierunek sortowania) za pomocą parametru ScanIndexForward .
Aktualizacja: w ten sam sposób można zamówić według atrybutu z lokalnym indeksem pomocniczym .
Możesz użyć klawisza sortowania i zastosować parametr ScanIndexForward w zapytaniu, aby posortować je w porządku rosnącym lub malejącym. Tutaj ograniczam elementy zwracane do 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));
}
});
Użyj ScanIndexForward (true dla rosnąco i false dla malejąco), a także możesz ograniczyć wynik za pomocą wartości setLimit wyrażenia zapytania.
Poniżej znajduje się kod, w którym użyto QueryPage do znalezienia pojedynczego rekordu.
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());
}
}
Inną opcją, która powinna rozwiązać problem, jest
Umożliwi to sortowanie dowolnej wartości tabeli zgodnie z wymaganiami. Jest to bardzo skuteczny sposób znajdowania elementów o najwyższej pozycji w tabeli bez konieczności pobierania całego zapytania, a następnie filtrowania go.
Jeśli używasz boto2 i masz klucz sortowania w jednej z kolumn w tabeli, możesz posortować to, co pobierasz w kolejności lub w odwrotnej kolejności, mówiąc:
result = users.query_2(
account_type__eq='standard_user',
reverse=True)
Jeśli używasz boto3 i masz klucz sortowania w kolumnie, według której chcesz posortować wynik, możesz posortować dane, które pobierasz, mówiąc:
result = users.query(
KeyConditionExpression=Key('account_type').eq('standard_user'),
ScanIndexForward=True)
Pamiętaj, że w boto3, jeśli ScanIndexForward ma wartość true, DynamoDB zwraca wyniki w kolejności, w jakiej są przechowywane (według wartości klucza sortowania). To jest zachowanie domyślne. Jeśli ScanIndexForward ma wartość false, DynamoDB odczytuje wyniki w odwrotnej kolejności według wartości klucza sortowania, a następnie zwraca wyniki do klienta.
Jeśli tabela już istniała, dodaj GSI (Global Secondary Index) do atrybutu, który chcesz dla tabeli i użyj zapytania, a nie skanowania. Jeśli masz zamiar utworzyć tabelę, możesz dodać LSI (lokalny indeks pomocniczy) do żądanego atrybutu.
Nigdy nie myślałem, że tak banalne zadanie może przerodzić się w problem w DynamoDB. Dynamo wymaga podstawowej partycji. Udało mi się uporządkować dane, dodając dodatkowy status kolumny, a następnie utworzyć indeks GSI przy użyciu obu pól. Zamawiam dane ze statusem = "aktywne" przez pole createdAt.
Utwórz GSI
{
IndexName: "createdAt",
KeySchema: [
{ AttributeName: "status", KeyType: "HASH" },
{ AttributeName: "createdAt", KeyType: "RANGE" }
],
Projection: { ProjectionType: "ALL" },
ProvisionedThroughput: {
ReadCapacityUnits: N,
WriteCapacityUnits: N
}
}
dane zapytania
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"
},
});