ElasticsearchRestTemplate
是spring-data-elasticsearch项目中的一个类,和其他spring项目中的template类似。
在新版的spring-data-elasticsearch中,ElasticsearchRestTemplate
代替了原来的ElasticsearchTemplate
。原因是ElasticsearchTemplate
基于TransportClient
,TransportClient
即将在8.x以后的版本中移除。ElasticsearchRestTemplate
基于RestHighLevelClient
,如果不手动配置RestHighLevelClient
bean,ElasticsearchRestTemplate
将使用org.springframework.boot.autoconfigure.elasticsearch.rest.RestClientConfigurations
默认配置的RestHighLevelClient
baen,此时es服务器应当使用默认9200端口。
@Data
@Document(indexName = "qas2")
public class EsDocument {
@Id
private String id;
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String title; //标题
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String keyWord; //关键字
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String content; //解答内容
@Field(type = FieldType.Keyword)
private String typeId; //类型id
}
@Service
public class EsService {
@Autowired
ElasticsearchRestTemplate template;
@Autowired
ObjectMapper objectMapper;
public SearchResult search(String text, String typeId, int pageNum, int pageSize) {
QueryBuilder queryStringQueryBuilder = QueryBuilders.queryStringQuery(text);
HighlightBuilder highlightBuilder = new HighlightBuilder()
//.fragmentSize(8)
.field("title").field("keyWord").field("content");
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder()
.must(queryStringQueryBuilder);
//根据类型
if (!StringUtils.isEmpty(typeId)) {
TermQueryBuilder termQuery = QueryBuilders.termQuery("typeId", typeId);
boolQueryBuilder.must(termQuery);
}
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(boolQueryBuilder)
.withHighlightBuilder(highlightBuilder)
.withPageable(PageRequest.of(pageNum, pageSize))
.build();
SearchResult searchResult = new SearchResult();
AggregatedPage<EsDocument> aggregatedPage =
template.queryForPage(searchQuery, EsDocument.class, new SearchResultMapper() {
@Override
public <EsDoument> AggregatedPage<EsDoument> mapResults(SearchResponse response, Class<EsDoument> clazz, Pageable pageable) {
long total = response.getHits().totalHits;
searchResult.setTotal(total);
SearchHit[] hits = response.getHits().getHits();
LinkedList<EsDocument> list = new LinkedList<>();
for (SearchHit hit : hits) {
String source = hit.getSourceAsString();
EsDocument document = null;
try {
document = objectMapper.readValue(source, EsDocument.class);
} catch (Exception e) {
//ignore
}
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
for (Map.Entry<String, HighlightField> entry : highlightFields.entrySet()) {
HighlightField field = entry.getValue();
try {
//org.apache.commons.beanutils.PropertyUtils
PropertyUtils.setProperty(document, field.getName(), highlightFieldToString(field));
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
//
}
}
list.add(document);
}
return new AggregatedPageImpl(list);
}
@Override
public <T> T mapSearchHit(SearchHit searchHit, Class<T> type) {
return null;
}
});
List<EsDocument> list = aggregatedPage.getContent();
searchResult.setData(list);
return searchResult;
}
private String highlightFieldToString(HighlightField field) {
Text[] texts = field.getFragments();
StringBuilder sb = new StringBuilder();
for (Text text : texts) {
sb.append(text.string());
}
return subStr(sb.toString());
}
}