Dynamodb excluir dados ao longo do tempo
Nesta página
Removendo dados antigos do dynamodb usando um atributo de data.
Meu caso de uso: remover dados antigos do dynamodb usando um atributo de data.
Coisas importantes a saber:
- Você não pode consultar uma tabela usando apenas o atributo de chave de intervalo (data, por exemplo).
- Você só pode consultar uma tabela usando a chave hash ou hash+range.
- Você não pode consultar uma tabela usando uma chave de hash com operações ‘<’ / ‘>’, apenas ‘=’.
Soluções possíveis:
- Digitalizar toda a mesa - isso pode ser muito caro
- Minha solução escolhida - Definindo um índice com chave de intervalo para a data e com uma chave de hash que seria bastante decente, como o dia do ano.
Eventualmente, exclua o conjunto de resultados em lote.
Notas: Construindo a entidade eu estava usando as anotações do Amazon Dynamo. Eu estava usando o DynamoDBQueryExpression para consultar, obtendo a página de resultados com o objeto Class definido.
cleanUpOldData
public static void cleanUpOldData(AmazonDynamoDB amazonDynamoDB, String dynamoDBTablesPrefix, String tableName,
String dateRangeField, String dateHashKey, String dateIndex, Class clazz) {
log.info(String.format("Cleaning old data from table: %s", tableName));
long cleanUpDateInMillis = (new Date()).getTime() - CLEAN_UP_TIME_MILLIS;
SimpleDateFormat dateFormatter = new SimpleDateFormat(DYNAMO_DATE_FORMAT);
final TimeZone utcTimeZone = TimeZone.getTimeZone("UTC");
dateFormatter.setTimeZone(utcTimeZone);
String cleanUpDate = dateFormatter.format(cleanUpDateInMillis);
Calendar calendar = Calendar.getInstance(utcTimeZone);
calendar.setTimeInMillis(cleanUpDateInMillis);
final String dailyHashKey = String.format("%s_%s", calendar.get(Calendar.YEAR), calendar.get(Calendar.DAY_OF_YEAR));
final String pastDayHashKey = String.format("%s_%s", calendar.get(Calendar.YEAR), calendar.get(Calendar.DAY_OF_YEAR)-1);
final String fullTableName = dynamoDBTablesPrefix + "_" + tableName;
final DynamoDBMapperConfig dbMapperConfig = new DynamoDBMapperConfig(new DynamoDBMapperConfig.TableNameOverride(fullTableName));
DynamoDBMapper mapper = new DynamoDBMapper(amazonDynamoDB, dbMapperConfig);
DynamoDBTableMapper dbTableMapper = mapper.newTableMapper(clazz);
final QueryResultPage dailyResultPage = getDailyQueryResultPage(dateRangeField, dateHashKey, dateIndex, cleanUpDate, dailyHashKey, dbTableMapper);
final QueryResultPage pastDayResultPage = getDailyQueryResultPage(dateRangeField, dateHashKey, dateIndex, cleanUpDate, pastDayHashKey, dbTableMapper);
deleteOldData(dbTableMapper, dailyResultPage, pastDayResultPage);
log.info(String.format("Completed cleaning old data from table: %s, %s items were deleted", tableName,
dailyResultPage.getCount() + pastDayResultPage.getCount()));
}
private static QueryResultPage getDailyQueryResultPage(String dateRangeField, String dateHashKey, String dateIndex,
String cleanUpDate, String dayHashKey, DynamoDBTableMapper dbTableMapper) {
HashMap<String, String > nameMap = new HashMap<>();
nameMap.put("#date", dateRangeField);
nameMap.put("#day", dateHashKey);
HashMap<String, AttributeValue> valueMap = new HashMap<>();
valueMap.put(":date", new AttributeValue().withS(cleanUpDate)) ;
valueMap.put(":day", new AttributeValue().withS(dayHashKey));
final DynamoDBQueryExpression dbQueryExpression = new DynamoDBQueryExpression()
.withIndexName(dateIndex)
.withConsistentRead(false)
.withKeyConditionExpression("#day = :day and #date < :date")
.withExpressionAttributeNames(nameMap)
.withExpressionAttributeValues(valueMap);
return dbTableMapper.query(dbQueryExpression);
}
private static void deleteOldData(DynamoDBTableMapper dbTableMapper, QueryResultPage dailyResultPage, QueryResultPage pastDayResultPage) {
if (dailyResultPage.getCount() > 0) {
dbTableMapper.batchDelete(dailyResultPage.getResults());
}
if (pastDayResultPage.getCount() > 0) {
dbTableMapper.batchDelete(pastDayResultPage.getResults());
}
}