Spring Boot3.2.5+JHipster8.4.0中按user.login过滤Elasticsearch查询
将JHipster项目从v7.9.4升级到v8.4.0时的Elasticsearch查询适配问题
问题概述
我正尝试将21-Points Health JHipster项目从v7.9.4升级到v8.4.0。v7.9.4版本使用Elasticsearch Java 7,新版本则使用Elasticsearch Java 8。我在实现按user.login添加过滤条件的布尔查询时遇到困难。
v7版本的有效实现
查询逻辑代码
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery().must(queryStringQuery(query)); if (SecurityUtils.isAuthenticated() && !SecurityUtils.hasCurrentUserThisAuthority(AuthoritiesConstants.ADMIN)) { queryBuilder = queryBuilder.filter(matchQuery("user.login", SecurityUtils.getCurrentUserLogin().orElse(""))); } Page<Points> page = pointsSearchRepository.search(queryBuilder, pageable);
对应的仓库方法
@Override public Page<Points> search(QueryBuilder query, Pageable pageable) { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query).withPageable(pageable).build(); return search(searchQuery); }
v8版本的无效实现及报错
我当前的实现无法正常工作:
if (SecurityUtils.isAuthenticated() && !SecurityUtils.hasCurrentUserThisAuthority(AuthoritiesConstants.ADMIN)) { QueryVariant filterByUser = new MatchQuery.Builder() .field("user.login") .query(SecurityUtils.getCurrentUserLogin().orElse("")) .build(); BoolQuery.Builder boolQueryBuilder = QueryBuilders.bool(); boolQueryBuilder.should(new Query(filterByUser)); query = new Query(boolQueryBuilder.build()).toString(); }
报错信息:Invalid query syntax!
PointsSearchRepository完整代码
package org.jhipster.health.repository.search; import co.elastic.clients.elasticsearch._types.query_dsl.QueryStringQuery; import java.util.List; import org.jhipster.health.domain.Points; import org.jhipster.health.repository.PointsRepository; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate; import org.springframework.data.elasticsearch.client.elc.NativeQuery; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.scheduling.annotation.Async; /** * Spring Data Elasticsearch repository for the {@link Points} entity. */ public interface PointsSearchRepository extends ElasticsearchRepository<Points, Long>, PointsSearchRepositoryInternal {} interface PointsSearchRepositoryInternal { Page<Points> search(String query, Pageable pageable); Page<Points> search(Query query); @Async void index(Points entity); @Async void deleteFromIndexById(Long id); } class PointsSearchRepositoryInternalImpl implements PointsSearchRepositoryInternal { private final ElasticsearchTemplate elasticsearchTemplate; private final PointsRepository repository; PointsSearchRepositoryInternalImpl(ElasticsearchTemplate elasticsearchTemplate, PointsRepository repository) { this.elasticsearchTemplate = elasticsearchTemplate; this.repository = repository; } @Override public Page<Points> search(String query, Pageable pageable) { NativeQuery nativeQuery = new NativeQuery(QueryStringQuery.of(qs -> qs.query(query))._toQuery()); return search(nativeQuery.setPageable(pageable)); } @Override public Page<Points> search(Query query) { SearchHits<Points> searchHits = elasticsearchTemplate.search(query, Points.class); List<Points> hits = searchHits.map(SearchHit::getContent).stream().toList(); return new PageImpl<>(hits, query.getPageable(), searchHits.getTotalHits()); } @Override public void index(Points entity) { repository.findOneWithEagerRelationships(entity.getId()).ifPresent(elasticsearchTemplate::save); } @Override public void deleteFromIndexById(Long id) { elasticsearchTemplate.delete(String.valueOf(id), Points.class); } }
其他尝试
我还尝试过在搜索仓库中使用Spring Data实现findByUserLogin()方法,但同样无效。
内容的提问来源于stack exchange,提问作者Matt Raible
相关产品推荐
相关产品推荐

