全文检索之springboot操作elasticsearch步骤
注:这里用到了spring data elasticserch框架
一:引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
二:配置文件配置elasticsearch连接
spring:
data:
elasticsearch:
cluster-name: my-elasticsearch #集群名称
cluster-nodes: 192.168.220.100:9300 #ip地址
三:创建实体类
@Document标注索引库名 和 索引库type
@Field设置每个字段的属性:type,store(是否存储),analyzer(分词)
例如:
@Document(indexName = "supergo", type = "goods")
public class GoodsEntity {
@Id
@Field(type = FieldType.Long, store = true)
private Long id;
@Field(type = FieldType.text, store = true, analyzer = "ik_max_word")
private String goods_name;
@Field(type = FieldType.keyword, store = true)
private String seller_id;
@Field(type = FieldType.keyword, store = true)
private String nick_name;
@Field(type = FieldType.Long, store = true)
private long brand_id;
四:创建Repository接口
//实体类的@Id所注解的数据项的数据类型, 必须与第二个泛型一致
public interface GoodsRepository extends ElasticsearchRepository<GoodsEntity,Long> {
}
五:将持久数据库的数据查出后存入elasticsearch中
@Resource
private GoodsMapper goodsMapper;
@Autowired
private GoodsRepository goodsRepository;
puclic void import(){
List<GoodsEntity> goodsList = goodsMapper.getGoodsList(); //mybatis查询数据库接口自己写出
goodsList.forEach(g->goodsRepository.save(g));
}
六:根据需要查询:查询方法太多用时查询api
下面是自己写的一个商场的检索代码
注解:keyword是搜索框传来的参数,filters集合是过滤条件,之后是分页参数
注意:除搜索框(用query)外,其他条件最好用filter查询,因为filter查询效率高
@Autowired
private GoodsRepository goodsRepository;
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
public SearchResult search(String keyword, Map<String,String> filters,int page,int size) {
//设置查询条件
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
.should(QueryBuilders.multiMatchQuery(keyword, "goods_name"));
//判断是否有过滤条件
if (filters != null && !filters.isEmpty()) {
filters.keySet().forEach(key -> boolQueryBuilder.filter(QueryBuilders.termQuery(key, filters.get(key))));
}
//设置查询条件
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(boolQueryBuilder)
//设置分页信息
.withPageable(PageRequest.of(page, size))
//设置聚合条件
.addAggregation(AggregationBuilders.terms("category_aggs").field("cname3"))
.addAggregation(AggregationBuilders.terms("brand_aggs").field("brand_name"))
//设置高亮显示
.withHighlightFields(new HighlightBuilder.Field("name").preTags("<em>").postTags("</em>"))
.build();
//执行查询
AggregatedPage<GoodsEntity> sResult = elasticsearchTemplate.queryForPage(searchQuery, GoodsEntity.class, new SearchResultMapper() {
@Override
public <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> aClass, Pageable pageable) {
List<GoodsEntity> goodsList = new ArrayList<>();
SearchHits searchHits = searchResponse.getHits();
searchHits.forEach(hits->{
GoodsEntity goodsEntity = new GoodsEntity();
goodsEntity.setId((Long) hits.getSource().get("id"));
goodsEntity.setGoods_name((String) hits.getSource().get("goods_name"));
goodsEntity.setSeller_id((String) hits.getSource().get("seller_id"));
goodsEntity.setNick_name((String) hits.getSource().get("nick_name"));
goodsEntity.setBrand_id((Integer) hits.getSource().get("brand_id"));
goodsEntity.setBrand_name((String) hits.getSource().get("brand_name"));
goodsEntity.setCategory1_id((Integer) hits.getSource().get("category1_id"));
goodsEntity.setCname1((String) hits.getSource().get("cname1"));
goodsEntity.setCategory2_id((Integer) hits.getSource().get("category2_id"));
goodsEntity.setCname2((String) hits.getSource().get("cname2"));
goodsEntity.setCategory3_id((Integer) hits.getSource().get("category3_id"));
goodsEntity.setCname3((String) hits.getSource().get("cname3"));
goodsEntity.setSmall_pic((String) hits.getSource().get("small_pic"));
goodsEntity.setPrice((Double) hits.getSource().get("price"));
//取高亮结果
HighlightField highlightField = hits.getHighlightFields().get("goods_name");
if (highlightField != null) {
String h1 = highlightField.getFragments()[0].string();
goodsEntity.setGoods_name(h1);
}
goodsList.add(goodsEntity);
});
AggregatedPageImpl<T> aggregatedPage = new AggregatedPageImpl<>((List<T>) goodsList, pageable, searchHits.totalHits, searchResponse.getAggregations());
return aggregatedPage;
}
});
//取查询结果
List<GoodsEntity> content = sResult.getContent();
//取三级分类聚合结果
Terms termsCat = (Terms) sResult.getAggregation("category_aggs");
List<String> catAggsList = termsCat.getBuckets().stream().map(e -> e.getKeyAsString()).collect(Collectors.toList());
Map catAggsMap = new HashMap();
catAggsMap.put("name","分类");
catAggsMap.put("field", "cname3");
catAggsMap.put("content", catAggsList);
//取品牌聚合结果
Terms termsBrand = (Terms) sResult.getAggregation("brand_aggs");
List<String> brandAggsList = termsBrand.getBuckets().stream().map(e -> e.getKeyAsString()).collect(Collectors.toList());
Map brandAggsMap = new HashMap();
brandAggsMap.put("name","品牌");
brandAggsMap.put("field", "brand_name");
brandAggsMap.put("content", brandAggsList);
List aggsList = new ArrayList();
aggsList.add(brandAggsMap);
aggsList.add(catAggsMap);
SearchResult searchResult = new SearchResult();
//存入搜索结果
searchResult.setGoodsList(content);
//存入聚合信息
searchResult.setAggs(aggsList);
return searchResult;
}