全文检索之springboot操作elasticsearch步骤

全文检索之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;
    
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值