Я создаю класс DAO, у которого есть API для получения продуктов постранично. В запросе к API будет список фильтров. Фильтрация работает должным образом для примитивных и строковых атрибутов.
@Getter
@Setter
@DynamoDBTable(tableName = "Entity")
public abstract class EntityDO {
@DynamoDBHashKey(attributeName = "uid")
@DynamoDBAutoGeneratedKey
private String uid;
}
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@DynamoDBDocument
@DynamoDBTable(tableName = "CATEGORIES")
public class CategoryDO extends EntityDO {
@DynamoDBAttribute(attributeName = "name")
private String name;
@DynamoDBAttribute(attributeName = "description")
private String description;
@DynamoDBAttribute(attributeName = "imageUrl")
private String imageUrl;
}
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@DynamoDBTable(tableName = "bs-PRODUCTS")
public class ProductDO extends EntityDO {
@DynamoDBAttribute(attributeName = "name")
private String name;
@DynamoDBAttribute(attributeName = "description")
private String description;
@DynamoDBAttribute(attributeName = "longDescription")
private String longDescription;
@DynamoDBAttribute(attributeName = "category")
private CategoryDO category;
@DynamoDBAttribute(attributeName = "imageUrl")
private String imageUrl;
@DynamoDBAttribute(attributeName = "mrp")
private float mrp;
@DynamoDBAttribute(attributeName = "discount")
private float discount;
@DynamoDBAttribute(attributeName = "tags")
private List<String> tags;
}
public class ProductDAO extends EntityDAO<ProductDO> {
@Autowired
private Logger logger;
@Autowired
private DynamoDBMapper dynamoDBMapper;
@Autowired
private Map<Filter.Operation, ComparisonOperator> operatorMap;
@Autowired
private ProductConverter converter;
@Override
public Optional<ProductDO> get(String id) {
return Optional.ofNullable(dynamoDBMapper.load(ProductDO.class, id));
}
@Override
public List<ProductDO> getAll() {
return dynamoDBMapper.scan(ProductDO.class, new DynamoDBScanExpression());
}
@Override
public List<ProductDO> get(List<Filter> filters, String previousPageLastKey, int count) {
Map<String, Condition> scanFilters = new HashMap<>();
for (Filter filter: filters) {
ComparisonOperator comparisonOperator = operatorMap.get(filter.getOperation());
Condition condition = new Condition()
.withComparisonOperator(comparisonOperator)
.withAttributeValueList(new AttributeValue().withS(filter.getAttributeValue()));
scanFilters.put(filter.getAttributeName(), condition);
}
DynamoDBScanExpression scanExpression = new DynamoDBScanExpression()
.withLimit(count)
.withScanFilter(scanFilters);
if (previousPageLastKey != null) {
Map<String, AttributeValue> exclusiveStartKey = new HashMap<>();
exclusiveStartKey.put(Constants.UID, new AttributeValue().withS(previousPageLastKey));
scanExpression.setExclusiveStartKey(exclusiveStartKey);
}
return dynamoDBMapper.scan(ProductDO.class, scanExpression);
}
}
Что нужно изменить в ScanExpression для фильтрации по category.uid?
Я попытался передать имя атрибута как category.uid
, но не помогло.
Я готов узнать мнение критика, если подход неверен с точки зрения дизайна. Если есть несколько способов, вы можете подробно рассказать о плюсах и минусах.
Более того, я пробовал это на консоли AWS, и там это тоже не работает. Моя таблица выглядит следующим образом:
Один из продуктов имеет содержимое, как показано ниже
Проверьте поле категории, которое представляет собой карту, содержащую name
и uid
. Я попытался найти название категории, и никаких результатов не появилось.
Поддерживает ли AWS DynamoDB фильтрацию по вложенным атрибутам?