【发布时间】:2019-11-17 20:01:58
【问题描述】:
我正在使用 Spring Boot 2.1.6 和 Elasticsearch 6.2.2
编辑以更好地澄清我的问题:
当我让 Spring 在我的存储库中使用以下方法为我生成查询时:
Account findTop1ByAccountIdOrderByCreatedDesc(final String accountId);
我想这意味着它将从按 accountId 过滤的索引中进行选择,然后按创建的降序对结果进行排序,最后它只会返回第一个(最新的)结果。
但我在索引中只有两个条目,相同的条目减去创建日期,并且该查询返回两个结果。我认为这意味着它不会转化为我的想法,而是会选择具有该 ID 的所有帐户(因为这是一个键,所以都是“顶部”),按降序排列。
这将更接近我的查询,但它不是合法的命名:
Account findTop1OrderByCreatedDescByAccountId(final String accountId);
org.springframework.data.mapping.PropertyReferenceException: No property descByAccountId found for type LocalDateTime! Traversed path: Account.created.
还有这个:
Account findTop1OrderByCreatedDescAndAccountIdEquals(final String accountId);
org.springframework.data.mapping.PropertyReferenceException: No property desc found for type LocalDateTime! Traversed path: Account.created.
那么,如果可能的话,我如何将我的查询转换为 Spring 存储库魔法?
/编辑
原问题:
我有一个这样声明的 POJO(精简版):
@Document(indexName = "config.account", type = "account")
public class Account{
@Id
private String id;
@Field(type = FieldType.Text)
@JsonProperty("ilmAccountIdentifier")
private String accountId;
@Field(type = FieldType.Text)
private String endOfBusinessDay;
@Field(type = FieldType.Date)
private LocalDateTime created;
}
我想查询索引以检索给定 accountId 的最新条目(created = max)。
我知道我可以使用查询生成器,但我想知道是否有一些魔法可以通过使用 spring 命名查询为我做到这一点,目前我正在尝试使用(找不到其他有效的措辞组合) :
Account findTop1ByAccountIdOrderByCreatedDesc(final String accountId);
但它返回 null。我看到数据在索引中(修剪版):
Account(id=W83u0GsBEjwDhWt1-Whn,
accountId=testfindByAccountIdReturnsLatestVersion,
endOfBusinessDay=17:00:00,
created=2019-07-08T09:34)
但是 Spring 生成的查询很奇怪,不是我所期望的:
SearchRequest{
searchType=QUERY_THEN_FETCH,
indices=[config.account],
indicesOptions=IndicesOptions[ignore_unavailable=false, allow_no_indices=true, expand_wildcards_open=true, expand_wildcards_closed=false, allow_aliases_to_multiple_indices=true, forbid_closed_indices=true, ignore_aliases=false],
types=[account],
routing='null',
preference='null',
requestCache=null,
scroll=null,
maxConcurrentShardRequests=0,
batchedReduceSize=512,
preFilterShardSize=128,
allowPartialSearchResults=null,
source={
"from":0,
"query":{
"bool":{
"must":[{
"query_string":
{"query":
"testfindByAccountIdReturnsLatestVersion",
"fields": ["accountId^1.0"],
"type":"best_fields",
"default_operator":"and",
"max_determinized_states":10000,
"enable_position_increments":true,
"fuzziness":"AUTO",
"fuzzy_prefix_length":0,
"fuzzy_max_expansions":50,
"phrase_slop":0,
"escape":false,
"auto_generate_synonyms_phrase_query":true,
"fuzzy_transpositions":true,
"boost":1.0}
}],
"adjust_pure_negative":true,"boost":1.0}
}
,"version":true}}
我想要的是这个 SQL 查询的等价物:
select *
from(
select *
from account
where accountId = ?
order by created desc
)
where rownum = 1
是否有可能与 Spring 魔法有关,还是我必须使用 QueryBuilder 或我自己的逻辑来实现它?
感谢和欢呼
编辑
不相关,但我意识到如果在使用 @JsonProperty 映射期间重命名字段,则 spring Repository 魔法不起作用。假设我不重命名,问题仍然是一样的。目前我通过实现我自己的逻辑来解决这个问题:
@Repository
public interface AccountRepository extends ElasticsearchRepository<Account, String>, AccountRepositoryCustom {
List<Account> findByIlmAccountIdentifierOrderByCreatedDesc(final String accountId);
}
public interface AccountRepositoryCustom {
Account findLatestByAccountId(final String accountId);
}
@Repository
public class AccountRepositoryImpl implements AccountRepositoryCustom {
@Autowired
@Lazy
private AccountRepository accountRepository;
public Account findLatestByAccountId(final String accountId){
return accountRepository.findByIlmAccountIdentifierOrderByCreatedDesc(accountId).get(0);
}
}
【问题讨论】:
标签: java spring spring-boot elasticsearch spring-data-elasticsearch