ElasticsearchRestTemplate操作方法
本次从以下几个内容分享:
- 导入依赖
- 配置连接ES的属性
- 编码实现
导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
这是我的spring-boot和data-es的版本
配置相关属性
我是使用JavaConfig的方式配置的
@Configuration
public class ElasticSearchConfig{
@Bean
public RestHighLevelClient restHighLevelClient(){
ClientConfiguration configuration = ClientConfiguration.builder()
.connectedTo("192.168.23.170:8999").build();
return RestClients.create(configuration).rest();
}
}
编码实现相关操作
先自动注入一个ElasticsearchRestTemplate再继续下面的操作
@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;
- 根据关键字查询
@Override
public Map search(Map<String, String> map) {
if (map == null) {
return null;
}
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
HashMap<String, Object> hashMap = new HashMap<>();
//根据关键字查询
if (StringUtils.isNotEmpty(map.get("keywords"))) {
MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("name", map.get("keywords")).operator(Operator.AND);
boolQuery.must(matchQuery);
}
nativeSearchQueryBuilder.withQuery(boolQuery);
SearchHits<SkuInfo> searchHits = elasticsearchRestTemplate.search(nativeSearchQueryBuilder.build(), SkuInfo.class);
}
- 根据规格查询
//根据规格过滤
for (String s : map.keySet()) {
if (s.startsWith("spec_")) {
TermQueryBuilder termQuery = QueryBuilders.termQuery("specMap." + s.substring(5) + ".keyword", map.get(s));
boolQuery.filter(termQuery);
}
}
- 根据商品品牌查询
//根据品牌进行过滤
if (StringUtils.isNotEmpty(map.get("brandName"))) {
TermQueryBuilder termQuery = QueryBuilders.termQuery("brandName", map.get("brandName"));
boolQuery.filter(termQuery);
}
- 分页查询
//开启分页查询
String pageNum = map.get("pageNum");
if (pageNum == null) {
pageNum = "1";
}
String pageSize = map.get("pageSize");
if (pageSize == null) {
pageSize = "30";
}
nativeSearchQueryBuilder.withPageable(PageRequest.of(Integer.parseInt(pageNum), Integer.parseInt(pageSize)));
- 根据价格区间来进行过滤
//根据价格区间查询
if (StringUtils.isNotEmpty(map.get("price"))) {
String[] prices = map.get("price").split("-");
boolQuery.filter(QueryBuilders.rangeQuery("price").gte(prices[0]));
if (prices.length > 1) {
boolQuery.filter(QueryBuilders.rangeQuery("price").lte(prices[1]));
}
}
nativeSearchQueryBuilder.withQuery(boolQuery);
- 字段高亮显示
//高亮显示某些字段
HighlightBuilder highlightBuilder = new HighlightBuilder().field("name")
.preTags("<span style='color:red'>")
.postTags("</span>");
nativeSearchQueryBuilder.withHighlightBuilder(highlightBuilder);
这是上面的完整代码
package com.ysdn.service.impl;
import com.ysdn.domain.SkuInfo;
import com.ysdn.service.SearchService;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author YS
*/
@Service
@Transactional
public class SearchServiceImpl implements SearchService {
@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;
@Override
public Map search(Map<String, String> map) {
if (map == null) {
return null;
}
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
HashMap<String, Object> hashMap = new HashMap<>();
//根据关键字查询
if (StringUtils.isNotEmpty(map.get("keywords"))) {
MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("name", map.get("keywords")).operator(Operator.AND);
boolQuery.must(matchQuery);
}
//根据品牌进行过滤
if (StringUtils.isNotEmpty(map.get("brandName"))) {
TermQueryBuilder termQuery = QueryBuilders.termQuery("brandName", map.get("brandName"));
boolQuery.filter(termQuery);
}
//根据规格过滤
for (String s : map.keySet()) {
if (s.startsWith("spec_")) {
QueryBuilders.termQuery("specMap." + s.substring(5) + ".keyword", map.get(s));
}
}
//根据价格区间查询
if (StringUtils.isNotEmpty(map.get("price"))) {
String[] prices = map.get("price").split("-");
if (prices.length > 1) {
QueryBuilders.rangeQuery("price").lte(prices[1]);
}
QueryBuilders.rangeQuery("price").gte(prices[0]);
}
nativeSearchQueryBuilder.withQuery(boolQuery);
//开启分页查询
String pageNum = map.get("pageNum");
if (pageNum == null) {
pageNum = "1";
}
String pageSize = map.get("pageSize");
if (pageSize == null) {
pageSize = "30";
}
nativeSearchQueryBuilder.withPageable(PageRequest.of(Integer.parseInt(pageNum), Integer.parseInt(pageSize)));
//按照相关字段排序
if (StringUtils.isNotEmpty(map.get("sortField"))) {
if (StringUtils.isNotEmpty(map.get("sortRule"))) {
if ("ASC".equals(map.get("sortRule"))) {
nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(map.get("sortField")).order(SortOrder.ASC));
} else {
nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(map.get("sortField")).order(SortOrder.DESC));
}
}
nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(map.get("sortField")));
}
//高亮显示某些字段
HighlightBuilder highlightBuilder = new HighlightBuilder().field("name")
.preTags("<span style='color:red'>")
.postTags("</span>");
nativeSearchQueryBuilder.withHighlightBuilder(highlightBuilder);
//按照品牌进行聚合查询
nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms("skuBrand").field("brandName"));
//按照价格区间进行聚合查询
nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms("skuSpec").field("spec.keyword").size(20));
//去ES中查询数据并返回击中的数据
SearchHits<SkuInfo> searchHits = elasticsearchRestTemplate.search(nativeSearchQueryBuilder.build(), SkuInfo.class);
Map<String, Aggregation> aggregationMap = searchHits.getAggregations().asMap();
hashMap.put("total", searchHits.getTotalHits());
hashMap.put("rows", searchHits.get());
//封装通过品牌查询的分组结果
ParsedStringTerms parsedStringTerms = (ParsedStringTerms) aggregationMap.get("skuBrand");
List<String> brandList = parsedStringTerms.getBuckets().stream().map(bucket -> bucket.getKeyAsString()).collect(Collectors.toList());
hashMap.put("brandList", brandList);
//封装规格查询的分组结果
ParsedStringTerms specStringTerms = (ParsedStringTerms) aggregationMap.get("skuSpec");
List<String> specList = specStringTerms.getBuckets().stream().map(bucket -> bucket.getKeyAsString()).collect(Collectors.toList());
hashMap.put("specList", specList);
hashMap.put("pageNum", pageNum);
return hashMap;
}
}
以上就是本次全部内容,如果有不恰当的地方,欢迎指正。