Spring Data DynamoDB - 存储库执行扫描而不是查询
Spring Data DynamoDB - Respository performing scan instead of query
预期行为
存储库对仅使用 hashKey 和 rangeKey 属性的方法执行查询,结果如下:
"{"TableName":"music","KeyConditionExpression":"artist = :_artist and begins_with(title, :_title)","ExpressionAttributeValues":{":_artist":{"S":"Djavan"},":_title":{"S":"Eu te devoro"}}}"
实际行为
存储库对仅使用 hashKey 和 rangeKey 属性的方法执行 scanFilter,结果如下:
"{"TableName":"music","ScanFilter":{"artist":{"AttributeValueList":[{"S":"Djavan"}],"ComparisonOperator":"EQ"},"title":{"AttributeValueList":[{"S":"Eu te devoro"}],"ComparisonOperator":"BEGINS_WITH"}}}"
重现问题的步骤
使用名为音乐的实体
@DynamoDBTable(tableName = "music")
data class Music(
@field:Id
@DynamoDBIgnore
val id: MusicId = MusicId(),
var genre: String? = null
) {
@DynamoDBHashKey(attributeName = "artist")
fun getArtist() = id.artist
fun setArtist(artist: String) {
id.artist = artist
}
@DynamoDBHashKey(attributeName = "title")
fun getTitle() = id.title
fun setTitle(title: String) {
id.title = title
}
}
@DynamoDBDocument
data class MusicId(
@field:DynamoDBHashKey(attributeName = "artist")
var artist: String? = null,
@field:DynamoDBRangeKey(attributeName = "title")
var title: String? = null
) : Serializable
还有一个存储库
@EnableScan //I know that if I remove this annotation, enables won't be permitted, but the problem is that the implementation code doesn't recognize my method as a key query and if I remove this annotation, the method falls on invocation
interface MusicRepository : CrudRepository<Music, MusicId> {
fun findByArtistAndTitleStartingWith(artista: String, sortKey: String): List<Music>
}
当我调用时:
@PostConstruct
fun init() {
println(musicRepository.findByArtistAndTitleStartingWith("Djavan", "Eu te devoro").joinToString())
}
日志显示了我对 AWS 的调用,如上所示
规格
- 库:https://github.com/boostchicken/spring-data-dynamodb
- Spring 数据 DynamoDB 版本:5.2.5
- Spring数据版本:未使用
- Spring 启动启动器 Web 版本:2.3.4.RELEASE
- AWS SDK 版本:1.11.573
- Java 版本: 11
- 平台详情:Windows
我是不是做错了什么?还是 spring 数据创建对 aws 的正确查询的另一种方法?
尝试随机更改实体后。我在存储库方法中得到了预期的结果。
使用复合键映射实体的正确方法
@DynamoDBTable(tableName = "music")
data class Music(
@get:DynamoDBHashKey(attributeName = "artist")
var artist: String? = null,
@get:DynamoDBRangeKey(attributeName = "title")
var title: String? = null,
var genre: String? = null
) {
@Id
private var id: MusicId? = null
get() = MusicId(artist, title)
}
@DynamoDBDocument
data class MusicId(
@field:DynamoDBHashKey(attributeName = "artist")
var artist: String? = null,
@field:DynamoDBRangeKey(attributeName = "title")
var title: String? = null
) : Serializable
更改实体并调用后:
musicRepository.findByArtistAndTitleStartingWith("Djavan", "Eu te devoro")
我得到了 AWS 的正确调用 api。
"{"TableName":"music","ConsistentRead":true,"KeyConditions":{"artist":{"AttributeValueList":[{"S":"Djavan"}],"ComparisonOperator":"EQ"},"title":{"AttributeValueList":[{"S":"Eu te devoro"}],"ComparisonOperator":"BEGINS_WITH"}},"ScanIndexForward":true}"
预期行为
存储库对仅使用 hashKey 和 rangeKey 属性的方法执行查询,结果如下:
"{"TableName":"music","KeyConditionExpression":"artist = :_artist and begins_with(title, :_title)","ExpressionAttributeValues":{":_artist":{"S":"Djavan"},":_title":{"S":"Eu te devoro"}}}"
实际行为
存储库对仅使用 hashKey 和 rangeKey 属性的方法执行 scanFilter,结果如下:
"{"TableName":"music","ScanFilter":{"artist":{"AttributeValueList":[{"S":"Djavan"}],"ComparisonOperator":"EQ"},"title":{"AttributeValueList":[{"S":"Eu te devoro"}],"ComparisonOperator":"BEGINS_WITH"}}}"
重现问题的步骤
使用名为音乐的实体
@DynamoDBTable(tableName = "music")
data class Music(
@field:Id
@DynamoDBIgnore
val id: MusicId = MusicId(),
var genre: String? = null
) {
@DynamoDBHashKey(attributeName = "artist")
fun getArtist() = id.artist
fun setArtist(artist: String) {
id.artist = artist
}
@DynamoDBHashKey(attributeName = "title")
fun getTitle() = id.title
fun setTitle(title: String) {
id.title = title
}
}
@DynamoDBDocument
data class MusicId(
@field:DynamoDBHashKey(attributeName = "artist")
var artist: String? = null,
@field:DynamoDBRangeKey(attributeName = "title")
var title: String? = null
) : Serializable
还有一个存储库
@EnableScan //I know that if I remove this annotation, enables won't be permitted, but the problem is that the implementation code doesn't recognize my method as a key query and if I remove this annotation, the method falls on invocation
interface MusicRepository : CrudRepository<Music, MusicId> {
fun findByArtistAndTitleStartingWith(artista: String, sortKey: String): List<Music>
}
当我调用时:
@PostConstruct
fun init() {
println(musicRepository.findByArtistAndTitleStartingWith("Djavan", "Eu te devoro").joinToString())
}
日志显示了我对 AWS 的调用,如上所示
规格
- 库:https://github.com/boostchicken/spring-data-dynamodb
- Spring 数据 DynamoDB 版本:5.2.5
- Spring数据版本:未使用
- Spring 启动启动器 Web 版本:2.3.4.RELEASE
- AWS SDK 版本:1.11.573
- Java 版本: 11
- 平台详情:Windows
我是不是做错了什么?还是 spring 数据创建对 aws 的正确查询的另一种方法?
尝试随机更改实体后。我在存储库方法中得到了预期的结果。
使用复合键映射实体的正确方法
@DynamoDBTable(tableName = "music")
data class Music(
@get:DynamoDBHashKey(attributeName = "artist")
var artist: String? = null,
@get:DynamoDBRangeKey(attributeName = "title")
var title: String? = null,
var genre: String? = null
) {
@Id
private var id: MusicId? = null
get() = MusicId(artist, title)
}
@DynamoDBDocument
data class MusicId(
@field:DynamoDBHashKey(attributeName = "artist")
var artist: String? = null,
@field:DynamoDBRangeKey(attributeName = "title")
var title: String? = null
) : Serializable
更改实体并调用后:
musicRepository.findByArtistAndTitleStartingWith("Djavan", "Eu te devoro")
我得到了 AWS 的正确调用 api。
"{"TableName":"music","ConsistentRead":true,"KeyConditions":{"artist":{"AttributeValueList":[{"S":"Djavan"}],"ComparisonOperator":"EQ"},"title":{"AttributeValueList":[{"S":"Eu te devoro"}],"ComparisonOperator":"BEGINS_WITH"}},"ScanIndexForward":true}"