我正在为项目使用spring-data- elasticsearch,以为其提供全文搜索功能。我们将真实数据保存在关系数据库中,并将相关元数据以及各自的ID保留在elasticsearch中。因此,对于搜索结果,仅需要id字段,因为将从关系数据库中检索实际数据。
我正在基于搜索条件构建搜索查询,然后执行queryForIds():
SearchQuery searchQuery = new NativeSearchQueryBuilder() .withIndices(indexName) .withTypes(typeName) .withQuery(getQueryBuilder(searchParams)) .withPageable(pageable) .build(); return elasticsearchTemplate.queryForIds(searchQuery);
如果我还需要该特定searchQuery的总数,则可以进行另一个elasticsearchTemplate.count(searchQuery)调用,但是据我所知这将是多余的。我认为有一种方法可以通过elasticsearchTemplate.queryForPage()在单个调用中使用类似的方法来获取ID列表和总数。
elasticsearchTemplate.count(searchQuery)
elasticsearchTemplate.queryForPage()
另外,我可以使用queryForPage(SearchQuery query, Class<T> clazz, SearchResultMapper mapper)不使用注释的自定义类@Document吗?实际的文档类确实很大,如果我不确定传递大型类是否会给引擎带来任何额外负担,因为有100多个字段要进行json映射,但是我所需要的只是id字段。.withFields("id")无论如何,我将在查询构建器中有一个。
queryForPage(SearchQuery query, Class<T> clazz, SearchResultMapper mapper)
@Document
.withFields("id")
如果要防止两次调用elasticsearch,我建议编写一个自定义的ResultsExtractor:
SearchQuery searchQuery = new NativeSearchQueryBuilder().withIndices(indexName) .withTypes(typeName) .withQuery(queryBuilder) .withPageable(pageable) .build(); SearchResult result = template.query(searchQuery, new ResultsExtractor<SearchResult>() { @Override public SearchResult extract(SearchResponse response) { long totalHits = response.getHits() .totalHits(); List<String> ids = new ArrayList<String>(); for (SearchHit hit : response.getHits()) { if (hit != null) { ids.add(hit.getId()); } } return new SearchResult(ids, totalHits); } }); System.out.println(result.getIds()); System.out.println(result.getCount());
其中SearchResult是自定义类:
public class SearchResult { List<String> ids; long count; //getter and setter }
这样,您可以从elasticsearch中获取所需的信息SearchResponse。
SearchResponse
关于您的第二个问题:据我所知,在调用queryForPage(SearchQuery query, Class<T> clazz, SearchResultMapper mapper) 传递的类时,不会检查@Document注释。试试看!