项目分享:搜索服务(二)2021-05-28

续上一期 查询了所有的sku 这一期我们主要整合ElasticSearch,完成一系列的查询操作 那么就开始今天的分享吧 冲~

初始化数据

搭建环境:搜索服务

  • 步骤一:构建项目changgou4-service-search
  • 步骤二:修改pom.xml,添加依赖
<dependencies>
    <!--自定义项目-->
    <dependency>
        <groupId>com.czxy.changgou</groupId>
        <artifactId>changgou4_common</artifactId>
    </dependency>
    <dependency>
        <groupId>com.czxy.changgou</groupId>
        <artifactId>changgou4_pojo</artifactId>
    </dependency>
    <!--web起步依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- nacos 客户端 -->
    <dependency>
        <groupId>com.alibaba.nacos</groupId>
        <artifactId>nacos-client</artifactId>
    </dependency>

    <!-- nacos 服务发现 -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>

    <!-- openfeign 远程调用 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>

    <!--swagger2-->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
    </dependency>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
    </dependency>

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

</dependencies>
  • 步骤三:创建yml文件
server:
  port: 8090
spring:
  application:
    name: search-service
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848   #nacos服务地址
  • 拷贝配置类
    在这里插入图片描述
package com.czxy.changgou4.config;

import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.RestClients;
import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;


@Configuration
@EnableElasticsearchRepositories
public class RestClientConfig extends AbstractElasticsearchConfiguration {

    @Override
    @Bean
    public RestHighLevelClient elasticsearchClient() {

        final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                .connectedTo("localhost:9200")
                .build();

        return RestClients.create(clientConfiguration).rest();
    }
}
  • 启动类
package com.czxy.changgou4;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;


@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class CGSearchServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(CGSearchServiceApplication.class,args);
    }
}

远程调用:查询所有

在这里插入图片描述

  • 步骤一:编写JavaBean,拷贝ESData,并添加elasticsearch相关注解
package com.czxy.changgou4.vo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
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.Date;
import java.util.Map;


@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(indexName = "skus", type = "docs" )
public class SearchSku {
    @Id
    private Long id; // skuId
    @Field(type = FieldType.Text)
    private String logo;//图片地址
    @Field(type = FieldType.Text)
    private String skuName;//sku名字
    @Field(type = FieldType.Text ,analyzer = "ik_max_word")
    private String all; // 所有需要被搜索的信息,包含标题,分类,甚至品牌
    @Field(type = FieldType.Date)
    private Date onSaleTime;//商家时间
    //品牌编号
    @Field(type = FieldType.Integer)
    private Integer brandId;
    // 分类id
    @Field(type = FieldType.Integer)
    private Integer catId;

    //规格列表
    //@IndexDynamicSettings
    private Map<String, Object> specs;// 可搜索的规格参数,key是参数名,值是参数值
    @Field(type = FieldType.Double)
    private Double price;// 价格
    @Field(type = FieldType.Text)
    private String spuName;
    @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;//售后保障
    @Field(type = FieldType.Text)
    private String midlogo;
    //评价数
    @Field(type = FieldType.Integer)
    private Integer commentCount;
    // 销量
    @Field(type = FieldType.Integer)
    private Integer sellerCount;

}
  • 步骤二:远程调用

package com.czxy.changgou4.feign;

import com.czxy.changgou4.vo.BaseResult;
import com.czxy.changgou4.vo.ESData;
import com.czxy.changgou4.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(value="web-service",path = "/sku")
public interface SkuFeign {

    @GetMapping("/esData")
    public BaseResult<List<SearchSku>> findESData();

}

  • 步骤三:测试类
    在这里插入图片描述
package com.czxy.changgou4;

import com.czxy.changgou4.feign.SkuFeign;
import com.czxy.changgou4.repository.SkuRepository;
import com.czxy.changgou4.vo.BaseResult;
import com.czxy.changgou4.vo.SearchSku;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;
import java.util.List;


@RunWith(SpringRunner.class)
@SpringBootTest(classes = CGSearchServiceApplication.class)
public class TestSkuClient {
    @Resource
    private SkuFeign skuFeign;

    @Test
    public void findAllSkus() throws Exception {
        BaseResult<List<SearchSku>> baseResult = skuFeign.findESData();
        List<SearchSku> list = baseResult.getData();
        System.out.println("总条数:" + list.size());
        for(SearchSku ss:list){
            System.out.println(ss);
        }
    }

}

整合ElasticSearch

  • 步骤一:创建repository类
    在这里插入图片描述
package com.czxy.changgou4.repository;

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


public interface SkuRepository extends ElasticsearchRepository<SearchSku, Long> {
}
  • 步骤二:测试创建索引
@Resource
private ElasticsearchRestTemplate elasticsearchRestTemplate;
@Test
public void createIndex(){
    // 创建索引
    this.elasticsearchRestTemplate.createIndex(SearchSku.class);
    // 配置映射
    this.elasticsearchRestTemplate.putMapping(SearchSku.class);
}
  • 步骤三:测试装载数据
@Resource
private SkuRepository skuRepository;

@Test
public void loadData() throws Exception {
    BaseResult<List<SearchSku>> baseResult = skuFeign.findESData();
    List<SearchSku> list = baseResult.getData();
    for(SearchSku ss:list){
        ss.setAll(ss.toString());
        System.out.println(ss);
    }
    this.skuRepository.saveAll(list);
}

基本查询

查询所有

package com.czxy.changgou4;

import com.czxy.changgou4.repository.SkuRepository;
import com.czxy.changgou4.vo.SearchSku;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;
import java.util.List;


@RunWith(SpringRunner.class)
@SpringBootTest(classes = CGSearchServiceApplication.class)
public class TestSkuRepository {
    @Resource
    private SkuRepository skuRepository;

    @Test
    public void testFind() {
        //1 简单条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        //2 复合条件
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        queryBuilder.withQuery(boolQueryBuilder);

        //3 查询
        Page<SearchSku> pageInfo = this.skuRepository.search(queryBuilder.build());

        // 总条数
        System.out.println(pageInfo.getTotalElements());

        // 查询结果
        pageInfo.getContent().forEach(System.out::println);

    }

}

根据分类查询

package com.czxy.changgou4;

import com.czxy.changgou4.repository.SkuRepository;
import com.czxy.changgou4.vo.SearchSku;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;
import java.util.List;


@RunWith(SpringRunner.class)
@SpringBootTest(classes = CGSearchServiceApplication.class)
public class TestSkuRepository {
    @Resource
    private SkuRepository skuRepository;

    @Test
    public void testFind() {
        //1 简单条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        // 1.1 根据分类查询
        boolQueryBuilder.must(QueryBuilders.termQuery("catId",76));


        //2 复合条件
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        queryBuilder.withQuery(boolQueryBuilder);

        //3 查询
        Page<SearchSku> pageInfo = this.skuRepository.search(queryBuilder.build());

        // 总条数
        System.out.println(pageInfo.getTotalElements());

        // 查询结果
        pageInfo.getContent().forEach(System.out::println);

    }

}

根据品牌查询

package com.czxy.changgou4;

import com.czxy.changgou4.repository.SkuRepository;
import com.czxy.changgou4.vo.SearchSku;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;
import java.util.List;


@RunWith(SpringRunner.class)
@SpringBootTest(classes = CGSearchServiceApplication.class)
public class TestSkuRepository {
    @Resource
    private SkuRepository skuRepository;

    @Test
    public void testFind() {
        //1 简单条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        // 1.1 根据分类查询
//        boolQueryBuilder.must(QueryBuilders.termQuery("catId",76));

        // 1.2 根据品牌查询
        boolQueryBuilder.must(QueryBuilders.termQuery("brandId",15127));

        //2 复合条件
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        queryBuilder.withQuery(boolQueryBuilder);

        //3 查询
        Page<SearchSku> pageInfo = this.skuRepository.search(queryBuilder.build());

        // 总条数
        System.out.println(pageInfo.getTotalElements());

        // 查询结果
        pageInfo.getContent().forEach(System.out::println);

    }

}

根据指定规格进行查询

package com.czxy.changgou4;

import com.czxy.changgou4.repository.SkuRepository;
import com.czxy.changgou4.vo.SearchSku;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;
import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = CGSearchServiceApplication.class)
public class TestSkuRepository {
    @Resource
    private SkuRepository skuRepository;

    @Test
    public void testFind() {
        //1 简单条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        // 1.1 根据分类查询
//        boolQueryBuilder.must(QueryBuilders.termQuery("catId",76));

        // 1.2 根据品牌查询
//        boolQueryBuilder.must(QueryBuilders.termQuery("brandId",15127));

        // 1.3 根据规格进行查询 机身颜色=灰色
        boolQueryBuilder.must(QueryBuilders.termQuery( "specs.机身颜色.keyword", "灰色"));

        //2 复合条件
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        queryBuilder.withQuery(boolQueryBuilder);

        //3 查询
        Page<SearchSku> pageInfo = this.skuRepository.search(queryBuilder.build());

        // 总条数
        System.out.println(pageInfo.getTotalElements());

        // 查询结果
        pageInfo.getContent().forEach(System.out::println);

    }

}

价格区间查询

package com.czxy.changgou4;

import com.czxy.changgou4.repository.SkuRepository;
import com.czxy.changgou4.vo.SearchSku;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;
import java.util.List;


@RunWith(SpringRunner.class)
@SpringBootTest(classes = CGSearchServiceApplication.class)
public class TestSkuRepository {
    @Resource
    private SkuRepository skuRepository;

    @Test
    public void testFind() {
        //1 简单条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        // 1.1 根据分类查询
//        boolQueryBuilder.must(QueryBuilders.termQuery("catId",76));

        // 1.2 根据品牌查询
//        boolQueryBuilder.must(QueryBuilders.termQuery("brandId",15127));

        // 1.3 根据规格进行查询 机身颜色=灰色
//        boolQueryBuilder.must(QueryBuilders.termQuery( "specs.机身颜色.keyword", "灰色"));

        // 1.4 范围查询:
        boolQueryBuilder.must(QueryBuilders.rangeQuery("price").gte(100000).lt(140000));


        //2 复合条件
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        queryBuilder.withQuery(boolQueryBuilder);

        //3 查询
        Page<SearchSku> pageInfo = this.skuRepository.search(queryBuilder.build());

        // 总条数
        System.out.println(pageInfo.getTotalElements());

        // 查询结果
        pageInfo.getContent().forEach(System.out::println);

    }

}

关键字查询

  • matchQuery 首先会解析查询字符串,进行分词,然后查询
  • term query 不分词,直接查询
package com.czxy.changgou4;

import com.czxy.changgou4.repository.SkuRepository;
import com.czxy.changgou4.vo.SearchSku;
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.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;
import java.util.List;


@RunWith(SpringRunner.class)
@SpringBootTest(classes = CGSearchServiceApplication.class)
public class TestSkuRepository {
    @Resource
    private SkuRepository skuRepository;

    @Test
    public void testFind() {
        //1 简单条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        // 1.1 根据分类查询
//        boolQueryBuilder.must(QueryBuilders.termQuery("catId",76));

        // 1.2 根据品牌查询
//        boolQueryBuilder.must(QueryBuilders.termQuery("brandId",15127));

        // 1.3 根据规格进行查询 机身颜色=灰色
//        boolQueryBuilder.must(QueryBuilders.termQuery( "specs.机身颜色.keyword", "灰色"));

        // 1.4 范围查询:
//        boolQueryBuilder.must(QueryBuilders.rangeQuery("price").gte(100000).lt(140000));

        // 1.5 关键字查询
        boolQueryBuilder.must(QueryBuilders.matchQuery("skuName","华为"));


        //2 复合条件
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        queryBuilder.withQuery(boolQueryBuilder);

        //3 查询
        Page<SearchSku> pageInfo = this.skuRepository.search(queryBuilder.build());

        // 总条数
        System.out.println(pageInfo.getTotalElements());

        // 查询结果
        pageInfo.getContent().forEach(System.out::println);

    }

}

分页

package com.czxy.changgou4;

import com.czxy.changgou4.repository.SkuRepository;
import com.czxy.changgou4.vo.SearchSku;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;
import java.util.List;


@RunWith(SpringRunner.class)
@SpringBootTest(classes = CGSearchServiceApplication.class)
public class TestSkuRepository {
    @Resource
    private SkuRepository skuRepository;

    @Test
    public void testFind() {
        //1 简单条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        // 1.1 根据分类查询
//        boolQueryBuilder.must(QueryBuilders.termQuery("catId",76));

        // 1.2 根据品牌查询
//        boolQueryBuilder.must(QueryBuilders.termQuery("brandId",15127));

        // 1.3 根据规格进行查询 机身颜色=灰色
//        boolQueryBuilder.must(QueryBuilders.termQuery( "specs.机身颜色.keyword", "灰色"));

        // 1.4 范围查询:
//        boolQueryBuilder.must(QueryBuilders.rangeQuery("price").gte(100000).lt(140000));


        //2 复合条件
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        queryBuilder.withQuery(boolQueryBuilder);

        //2.1 分页查询
        // 第一页 : 从0开始
        queryBuilder.withPageable(PageRequest.of(0  ,6));


        //3 查询
        Page<SearchSku> pageInfo = this.skuRepository.search(queryBuilder.build());

        // 总条数
        System.out.println(pageInfo.getTotalElements());

        // 查询结果
        pageInfo.getContent().forEach(System.out::println);

    }

}

排序

package com.czxy.changgou4;

import com.czxy.changgou4.repository.SkuRepository;
import com.czxy.changgou4.vo.SearchSku;
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.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;
import java.util.List;


@RunWith(SpringRunner.class)
@SpringBootTest(classes = CGSearchServiceApplication.class)
public class TestSkuRepository {
    @Resource
    private SkuRepository skuRepository;

    @Test
    public void testFind() {
        //1 简单条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        // 1.1 根据分类查询
//        boolQueryBuilder.must(QueryBuilders.termQuery("catId",76));

        // 1.2 根据品牌查询
//        boolQueryBuilder.must(QueryBuilders.termQuery("brandId",15127));

        // 1.3 根据规格进行查询 机身颜色=灰色
//        boolQueryBuilder.must(QueryBuilders.termQuery( "specs.机身颜色.keyword", "灰色"));

        // 1.4 范围查询:
//        boolQueryBuilder.must(QueryBuilders.rangeQuery("price").gte(100000).lt(140000));


        //2 复合条件
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        queryBuilder.withQuery(boolQueryBuilder);

        //2.1 分页查询
        // 第一页 : 从0开始
//        queryBuilder.withPageable(PageRequest.of(0  ,6));

        //2.2 排序
        queryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.ASC));

        //3 查询
        Page<SearchSku> pageInfo = this.skuRepository.search(queryBuilder.build());

        // 总条数
        System.out.println(pageInfo.getTotalElements());

        // 查询结果
        pageInfo.getContent().forEach(System.out::println);

    }

}

看完如果对你有帮助,感谢点赞支持!
如果你是电脑端,看到右下角的 一键三连 了吗,没错点它[哈哈]

在这里插入图片描述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值