集成ES
pom.xml
<!--Elasticsearch相关依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
application.yml
spring:
elasticsearch:
rest:
uris: 你的ip:9200
代码
- 实体
/**
* 商品主表---对应的ES数据Document
*/
@Data
@Document(indexName = "shop_product")
public class ESProduct implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private Long id;
private Long category_id;
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String name;
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String sub_title;
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String keywords;
private String pic;
private Integer sort;
private BigDecimal price;
}
- controller
@ApiOperation("ES分页搜索-所有商品")
@RequestMapping(value = "/SearchGoods", method = RequestMethod.POST)
public ResponseCon<ESProductVo> SearchGoods(Integer pageStart, Integer pageSize, String query,
String filtration, String interval, String SortField, String sort) {
log.info("=======ES搜索参数=======");
log.info("开始页: "+ pageStart);
log.info("行数: "+ pageSize);
log.info("搜索框字符串: "+ query);
log.info("过滤字段: "+ filtration);
log.info("价格区间: "+ interval);
log.info("排序字段: "+ SortField);
log.info("顺序: "+ sort);
log.info("执行搜索...");
//filtration = "category_id:12";
//interval = "0-10";
//或
//interval = "100-*";
ESProductVo esProductVo = esProductService.SearchGoods(pageStart, pageSize, query, filtration, interval, SortField, sort);
return new ResponseCon<>(200, "success", esProductVo);
}
- service,新版官方是推荐使用ElasticsearchOperations和ESProductDao的
@Resource
private ESProductDao esProductDao;
@Resource
private ElasticsearchOperations operations;
/**
* 搜索ES商品
*/
@Override
public ESProductVo SearchGoods(Integer pageStart, Integer pageSize, String query, String filtration, String interval, String sortField, String sort) {
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
//条件
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
//搜索框的字符串查询,为空则查询全部
if (query != null && !query.equals("") && !query.equals("null")) {
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("keywords", query);
boolQueryBuilder.must(termQueryBuilder);
}
//筛选字段
if (filtration != null && !filtration.equals("")) {
String[] strings = filtration.split(":");
MatchPhraseQueryBuilder matchPhraseQueryBuilder = QueryBuilders.matchPhraseQuery(strings[0], strings[1]);
boolQueryBuilder.must(matchPhraseQueryBuilder);
}
//价格区间过滤
if (interval != null && !interval.equals("")) {
String[] strings = interval.split("-");
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("price");
if(!strings[1].equals("*")){
//区间
rangeQueryBuilder.from(Integer.parseInt(strings[0])).to(Integer.parseInt(strings[1]));
} else {
//大于或等于 strings[0] 就是 100-*
rangeQueryBuilder.gte(Integer.parseInt(strings[0]));
}
boolQueryBuilder.must(rangeQueryBuilder);
}
//价格排序, 升序or倒序
if (sortField != null && !sortField.equals("")) {
if (sort.equals("desc")) {
nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(sortField).order(SortOrder.DESC));
} else {
nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(sortField).order(SortOrder.ASC));
}
}
//分页
nativeSearchQueryBuilder.withPageable(PageRequest.of(pageStart, pageSize));
//构建高亮查询域, 两个字段
HighlightBuilder highlightBuilder = new HighlightBuilder()
.field("sub_title")
.field("name")
.preTags("<b style='color:red'>").postTags("</b>").requireFieldMatch(false);
//构造查询
nativeSearchQueryBuilder.withHighlightBuilder(highlightBuilder);
nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
NativeSearchQuery build = nativeSearchQueryBuilder.build();
//获取查询结果
SearchHits<?> searchHits = operations.search(build, Map.class, IndexCoordinates.of("shop_product"));
//组装查询结果
ArrayList<ESProduct> list = new ArrayList<>();
for (SearchHit<?> hit : searchHits) {
Map<String, Object> content = (Map<String, Object>) hit.getContent();
Map<String, List<String>> highlightFields = hit.getHighlightFields();
//替换高亮文本
if (highlightFields.size() > 0) {
for (String key : highlightFields.keySet()) {
content.put(key,highlightFields.get(key).get(0));
}
}
//只留第一张图片
String pics = (String) content.get("pic");
String stringPic = pics.substring(0, pics.indexOf(","));
content.put("pic", stringPic);
list.add(JSON.parseObject(JSON.toJSONString(content), ESProduct.class));
}
//返回包装类
ESProductVo esProductVo = new ESProductVo();
esProductVo.setProducts(list);
esProductVo.setTotal(searchHits.getTotalHits());
return esProductVo;
}
- dao
/**
* 商品ES操作类DAO,Repository方式
* 第一个泛型是实体类类型,第二个泛型是id的类型
* 继承ElasticsearchRepository对实体数据映射操作
*/
@Repository
public interface ESProductDao extends ElasticsearchRepository<ESProduct, Long> {
// 比如
// List<ESProduct> findByName(String name);
// List<ESProduct> findByNameOrDesc(String a,String text);
}
- 测试,你先要把数据库中的商品导入到es中。。。