elasticSearch整合springboot

1.引入maven包

        <!--        el-search-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
        

2.配置yml文件

spring:
  data:
    elasticsearch:
      cluster-name: elasticsearch
      cluster-nodes: 127.0.0.1:9300

3.分页搜索使用


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import java.util.Map;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Setter
@Document(indexName = "skus01", type = "docs", shards = 5, replicas = 1)
public class SearchSku {
    @Id
    private Integer id; // skuId
    @Field(type = FieldType.Keyword, index = false)//不分词不索引只存储
    private String logo;//图片地址
    @Field(type = FieldType.Text, analyzer = "ik_max_word")// 分词索引存储
    private String sku_name;//sku名字
    @Field(type = FieldType.Text, analyzer = "ik_max_word")
    private String all; //用于关键字搜索, 所有需要被搜索的信息,包含标题,分类,甚至品牌
    // @Field(type = FieldType.Date)
// private Date on_sale_time;//上架时间--用于时间排序
    @Field(type = FieldType.Long)
    private Long on_sale_time;//上架时间--用于时间排序
    //品牌编号
    @Field(type = FieldType.Integer)
    private Integer brand_id;
    // 分类id
    @Field(type = FieldType.Integer)
    private Integer cat3_id;
    //规格列表 : {"机身颜色":"白色","内存":"3GB","机身存储":"16GB"}
    private Map<String, Object> specs;// 可搜索的规格参数,key是参数名,值是参数值
    @Field(type = FieldType.Double)
    private Double price;// 价格
    @Field(type = FieldType.Text)
    private String spu_name;
    @Field(type = FieldType.Integer)
// 库存量
    private Integer stock;
    @Field(type = FieldType.Text)
    private String description;
    @Field(type = FieldType.Text)
    private String packages;//规格与包装
    @Field(type = FieldType.Text)
    private String aftersale;//售后保障
    //private String midlogo;
//评价数
    @Field(type = FieldType.Integer)
    private Integer comment_count;
    // 销量
    @Field(type = FieldType.Integer)
    private Integer seller_count;
}

关于注解的用法:Elasticsearch搜索引擎一些参数含义和用法_瑶山的博客-CSDN博客


import com.czxy.vo.SearchSku;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

@FeignClient(name="web-service")
@RequestMapping
public interface SkuClient {
    @GetMapping("/esData")
    public ResponseEntity<List<SearchSku>> findESData();
}

feign 调用远程服务,用来查询所有商品 。

import com.czxy.vo.SearchSku;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

public interface SkuRepository extends ElasticsearchRepository<SearchSku,Integer> {
}

import com.czxy.client.SkuClient;
import com.czxy.dao.SkuRepository;
import com.czxy.vo.ReturnSku;
import com.czxy.vo.SearchResult;
import com.czxy.vo.SearchSku;
import com.czxy.vo.SkuSearchRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class SkuSearchService {
    @Autowired
    private SkuRepository skuRepository;
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;
    @Autowired
    private SkuClient skuClient;

    public void creatClient() {
        // 创建索引
        this.elasticsearchTemplate.createIndex(SearchSku.class);
        // 配置映射
        this.elasticsearchTemplate.putMapping(SearchSku.class);
        ResponseEntity<List<SearchSku>> resp = skuClient.findESData();
        List<SearchSku> list = resp.getBody();
        skuRepository.saveAll(list);
    }

    public void initeData() {
        ResponseEntity<List<SearchSku>> resp = skuClient.findESData();
        List<SearchSku> list = resp.getBody();
        skuRepository.saveAll(list);
    }

    /**
     * 搜索
     *
     * @param req
     * @return
     */
    public SearchResult findSkuByCondition(SkuSearchRequest req) {
        System.out.println("req:" + req);
        //初始化数据
        boolean exists = elasticsearchTemplate.indexExists("skus01");
        if (!exists) {
            creatClient();
        }
        Page<SearchSku> skuPage = skuRepository.search(new NativeSearchQueryBuilder().build());
        if (skuPage.getSize() == 0) {
            initeData();
        }
//1. 准备自定义查询的对象
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
//2. 多条件搜索依赖BoolQuery
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//3. 条件一:验证es中的cat3id和页面传过来的catid相等
// es中如何比较Integer类型相等
        boolQueryBuilder.must(QueryBuilders.termQuery("cat3_id", req.getCatid()));
//        4. 条件二:验证brand_id
        if (req.getBrand_id() != null && !"".equals(req.getBrand_id())) {
            boolQueryBuilder.must(QueryBuilders.termQuery("brand_id", req.getBrand_id()));
        }
        //5. 条件三:规格搜索
//5.1 将规格转成Map集合
        HashMap<String, String> map = null;
// 判断spec_list是否有值
        if (!"".equals(req.getSpec_list())) {
            map = new HashMap<>();
//1. 分割字符 机身颜色=金色 内存=4GB 机身颜色=
            String[] spec_list_array = req.getSpec_list().split(",");
//2. 遍历数组
            for (String s : spec_list_array) {
//3. 根据等号切割字符串
                String[] values = s.split("=");
//4. values[0] 机身颜色 内存
// values[1] 金色 4GB
                if (values.length == 1) {
//5. 当机身颜色没有对应的数据的时候,表明页面选择的是“不限”,此处就可以删除
                    map.remove(values[0]);
                } else {
                    map.put(values[0], values[1]);
                }
            }
        }
//5.2 添加过滤规格的条件
        if (map != null) {
// 遍历Map集合
            Set<String> keys = map.keySet();
            for (String key : keys) {
                String value = map.get(key);
/**
 * 拿着key和value去es中匹配
 * es中的列:
 * specs.机身颜色
 * specs.内存
 * specs.机身存储
 * 所以我们需拼接
 * specs: 是es中的map对象的名字
 * key: map集合中的key
 * .keyword:固定搭配
 **/
                key = "specs." + key + ".keyword";
// 添加条件
                boolQueryBuilder.must(QueryBuilders.termQuery(key, value));
            }
        }
//        6. 价格
        if (req.getMin_price() != null) {
            boolQueryBuilder.must(QueryBuilders.rangeQuery("price").gte(req.getMin_price()));
        }
        if (req.getMax_price() != null) {
            boolQueryBuilder.must(QueryBuilders.rangeQuery("price").lte(req.getMax_price()));
        }
//     7  排序
// 7销量
        if ("xl".equals(req.getSort_by())) {
            queryBuilder.withSort(SortBuilders.fieldSort("seller_count").order(SortOrder.DESC)
            );
        }
// 评论
        else if ("pl".equals(req.getSort_by())) {
            queryBuilder.withSort(SortBuilders.fieldSort("comment_count").order(SortOrder.DESC
            ));
        }
// 上架时间
        else if ("sj".equals(req.getSort_by())) {
            queryBuilder.withSort(SortBuilders.fieldSort("on_sale_time").order(SortOrder.DESC)
            );
        }
// 价格
        else if ("jg".equals(req.getSort_by()) && "desc".equals(req.getSort_way())) {
            queryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.DESC));
        } else if ("jg".equals(req.getSort_by()) && "asc".equals(req.getSort_way())) {
            queryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.ASC));
        }
//        8. 分页
        int pageNo = req.getPage() - 1;//为什么要减1,因为elasticsearch的分页从0开始
        int size = req.getPer_page();
        queryBuilder.withPageable(PageRequest.of(pageNo, size));
//9. queryBuilder关联boolQueryBuilder
        queryBuilder.withQuery(boolQueryBuilder);
//10. 执行查询
        Page<SearchSku> page = skuRepository.search(queryBuilder.build());
        for (SearchSku searchSku : page) {
            System.out.println("page:" + searchSku);
        }
//11. 获取总数量
        long count = page.getTotalElements();
//12. 获取catid
        Integer catid = req.getCatid();
//13. 准备data
//13.1 准备List<ReturnSku>
        ArrayList<ReturnSku> list = new ArrayList<>();
        for (SearchSku s : page) {
// 准备ReturnSku需要的数据
            ReturnSku sku = new ReturnSku();
            sku.setId(s.getId());
            sku.setGoods_name(s.getSku_name());
            sku.setPrice(s.getPrice());
            sku.setMidlogo(s.getLogo());
            sku.setComment_count(s.getComment_count());
// 装进集合
            list.add(sku);
        }
//14. 准备SearchResult
        SearchResult sr = new SearchResult(0, "成功", list, (int) count, catid);
        return sr;
    }

}

import com.czxy.service.SkuSearchService;
import com.czxy.vo.BaseResult;
import com.czxy.vo.SearchResult;
import com.czxy.vo.SkuSearchRequest;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping
public class SkuSearchController {
    @Autowired
    private SkuSearchService skuSearchService;
    @GetMapping("/goods")
    public ResponseEntity<Object> findSkus(SkuSearchRequest req){
        SearchResult search = skuSearchService.findSkuByCondition(req);
        Map<String, Object> map = new HashedMap();
        map.put("data", search);
        return ResponseEntity.ok(map);
    }

}

elasticSearch  其他用法 


import com.czxy.YoupingouWebSearchApplication;
import com.czxy.client.SkuClient;
import com.czxy.dao.SkuRepository;
import com.czxy.vo.SearchSku;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;
import java.util.Map;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = YoupingouWebSearchApplication.class)
public class SkuClientTest {
    @Autowired
    private SkuClient skuClient;
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;
    @Autowired
    private SkuRepository skuRepository;
    //    获取web-service数据
    @Test
    public void findAllSkus() throws Exception {
        ResponseEntity<List<SearchSku>> resp = skuClient.findESData();
        List<SearchSku> list = resp.getBody();
        for(SearchSku ss:list){
            System.out.println(ss);
        }
    }

    //    ****************************************  elasticSearch  使用  ************************************************************************

    //    创建索引
    @Test
    public void createIndex(){
    // 创建索引
        this.elasticsearchTemplate.createIndex(SearchSku.class);
    // 配置映射(创建索引类型)
        this.elasticsearchTemplate.putMapping(SearchSku.class);
    }

    //删除索引
    @Test
    public void deleteIndex(){
        this.elasticsearchTemplate.deleteIndex(SearchSku.class);
    }

    //导入数据
    @Test
    public void loadData() throws Exception {
        ResponseEntity<List<SearchSku>> resp = skuClient.findESData();
        List<SearchSku> list = resp.getBody();
        for(SearchSku ss:list){
            ss.setAll(ss.toString());
            System.out.println(ss);
        }
        this.skuRepository.saveAll(list);
    }

    //查询索引是否存在
    @Test
    public void findIndex() {
//        IndicesExistsResponse response = elasticsearchTemplate.getClient().admin().indices()
//                .exists(new IndicesExistsRequest().indices(new String[]{"skus01"})).actionGet();
//        boolean exists = response.isExists();
        boolean exists = elasticsearchTemplate.indexExists("skus01");
        System.out.println(exists);
    }

    //查询索引数据
    @Test
    public void  findDatas(){
        Page<SearchSku> page = skuRepository.search(new NativeSearchQueryBuilder().build());
        System.out.println("page:" + page.getSize());
        for (SearchSku searchSku : page) {
            System.out.println("page:" + searchSku);
        }
    }


}

另外还有其他查询用法:ElasticSearch之JavaAPI查询索引(9种)_fengge18306的博客-CSDN博客_java查询es索引 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值