es集成SpringCloud

1、es的使用

注意:

es在微服务中有很多地方都在使用, 所以es也是一个单独的微服务,其他微服务在使用es,那么就需要通过feign来调用es这个微服务

1.1 导包

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

1.2 es的配置文件 application.yml

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:1010/eureka/  #注册中心服务端的注册地址
  instance:
    prefer-ip-address: true #使用ip进行注册
    instance-id: es-server:2030  #服务注册到注册中心的id
server:
  port: 2030

#应用的名字
spring:
  application:
    name: es-server
  #es的主要配置
  data:
    elasticsearch:
      cluster-name: elasticsearch
      cluster-nodes: 127.0.0.1:9300 #9200是图形界面端,9300代码端

#超时
ribbon: #ribbon超时
  ReadTimeout: 50000
  ConnectTimeout: 50000
hystrix:  #hystrix超时
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 50000

1.3 创建CourseDoc

注意:

要上线放到es里的数据,那么其中的索引那些就是通过自定义doc类来配置的(这个doc类里面就包含了映射规则,索引库,分词和不分词)。类似于前台网站要进行查询、排序展示的数据就是通过这个规则来执行的。

一般会把CourseDoc对象 抽取成公共的hrm-es-common

/**
 * 针对于  Course表的文档映射
 * indexName:索引库
 * type:类型(表类型)
 */
 //针对于CourseDoc课程的ES文档对象    数据库/类型/id
 @Document(indexName = "hrm",type = "employee")
public class CourseDoc{

    //文档的ID,同时也是数据的id
    @Id
    private Long id;
    //标题  标题   要分词  FieldType.Text
    @Field(type =FieldType.Text,analyzer = "ik_max_word",searchAnalyzer = "ik_max_word")
    private String name;
    //适用人群
    @Field(type =FieldType.Text,analyzer = "ik_max_word",searchAnalyzer = "ik_max_word")
    private String users;
    //课程类型ID
    @Field(type = FieldType.Long)
    private Long courseTypeId;
    //等级名字
//    @Field(type = FieldType.Keyword)
    private String gradeName;
    //课程等级
    private Long gradeId;
    //机构id
    private Long tenantId;
    //机构名字
    @Field(type =FieldType.Text,analyzer = "ik_max_word",searchAnalyzer = "ik_max_word")
    private String tenantName;
    //开课时间
    private Date startTime;
    //结课时间
    private Date endTime;
    //封面
    private String pic;
    //免费、收费
    private String chargeName;
    //qq
    private String qq;
    //价格
    private Float price;
    //原价
    private Float priceOld;
    //课程介绍
    private String description;
    //上线时间
    private Date onlineDate = new Date();
    //浏览数
    private Integer viewCount;
    //购买数
    private Integer buyCount;




	//------------get/set---------
 	public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
    .........
}

1.4 创建CourseDocRepository

import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;

/**
 *   ElasticsearchRepository<要操做的映射类的类型,主键类型>
 *      这个接口里面有基础的crud,所以需要继承这个接口
 */

//使用的时候就直接注入这个接口就可以了
@Repository
public interface CourseDocRepository extends ElasticsearchRepository<CourseDoc,Long> {

}

1.5 普通的测试(可有可无)

import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
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.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.Iterator;
import java.util.List;
import java.util.Optional;


@RunWith(SpringRunner.class)
@SpringBootTest(classes = Es_App_2030.class) //主配置类
public class EsTest {

    //创建索引,并且建立类型映射
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate; //直接注入,springboot已经做了自动配置

    @Autowired
    private CourseDocRepository courseDocRepository;

    @Test
    public void testPre() throws Exception{

        //创建索引
        elasticsearchTemplate.createIndex(CourseDoc.class);
        //类型映射-自定义映射
        elasticsearchTemplate.putMapping(CourseDoc.class);
    }


    @Test
    public void test() throws Exception{
        CourseDoc courseDoc = new CourseDoc();
        courseDoc.setId(1L);
        courseDoc.setName("欢迎来到非诚勿扰");
        courseDoc.setGradeName("黄金30秒");

        courseDocRepository.save(courseDoc);
    }

    /**
     *  获取全部
     * @throws Exception
     */
    @Test
    public void testGetAll() throws Exception{


        Iterable<CourseDoc> all = courseDocRepository.findAll();

        all.forEach(e-> System.out.println(e));

    }

    //获取一个
    @Test
    public void testGetOne() throws Exception{
        System.out.println(courseDocRepository.findById(1L));
    }

    //修改:先查询出来,在进行修改
    @Test
    public void testUpdate() throws Exception{

        Optional<CourseDoc> byId = courseDocRepository.findById(1L);
        //将查询出来的数据进行修改,然后在将这个数据保存
        CourseDoc doc = byId.get();
        doc.setName("你好啊");

        courseDocRepository.save(doc);

    }

    //删除
    @Test
    public void testDel() throws Exception{
        courseDocRepository.deleteById(1L);
    }



    //高级查询分页排序: DSL查询+DSL过滤
    // 需求:查询 name中包含 “Java”的课程,
    // 并且课程分类 CourseTypeId 在 1 - 10
    //课程等级 GradeName为“神级”
    //查询第2页,每页2条
    //按照id倒排序
    @Test
    public void testSearchCourse(){
        //查询对象构建器
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();

        //查询条件start======================================================================================================
        //组合查询
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        //查询 name中包含 “Java”的课程 : matchQuery  , termQuery
        boolQueryBuilder.must(QueryBuilders.matchQuery("name","Java"));


        List<QueryBuilder> filter = boolQueryBuilder.filter();
        //分类 CourseTypeId 在 1 - 10 : rangeQuery
        filter.add(QueryBuilders.rangeQuery("courseTypeId").gte(1).lte(20) );

        //等级 GradeName为“神级” : termQuery
        filter.add(QueryBuilders.termQuery("gradeName","神级"));

        //添加查询条件
        nativeSearchQueryBuilder.withQuery(boolQueryBuilder);

        //查询条件end======================================================================================================

        //添加分页
        nativeSearchQueryBuilder.withPageable(PageRequest.of(0,2));

        //添加排序
        nativeSearchQueryBuilder.withSort(new FieldSortBuilder("id").order(SortOrder.DESC));

        //查询对象
        SearchQuery searchQuery = nativeSearchQueryBuilder.build();

        //查询结果:page相当于是以前的PageList
        Page<CourseDoc> page = courseElasticsearchRepository.search(searchQuery);

        //总条数 PageList: count ,list
        long count = page.getTotalElements();
        //总 页数
        int totalPages = page.getTotalPages();
        //结果列表
        List<CourseDoc> list = page.getContent();
        System.out.println("总条数:"+count);
        System.out.println("totalPages:"+totalPages);
        System.out.println("数据列表:");

        list.forEach(c->{
            System.out.println(c);
        });
    }


}

1.6 项目使用(es集成一个controller接口)

类似于redis,方便其他微服务调用

import com.alibaba.fastjson.JSON;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.FieldSortBuilder;
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.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

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


@RestController
@RequestMapping("/es")
public class EsController {

    @Autowired
    private CourseDocRepository courseDocRepository;

    //保存
    @PostMapping("/save")
    public AjaxResult save(@RequestBody CourseDoc courseDoc){
        courseDocRepository.save(courseDoc);
        return AjaxResult.me();
    }

    //删除
    @DeleteMapping("/delete/{id}")
    public AjaxResult del(@PathVariable("id")Long id){
        courseDocRepository.deleteById(id);
        return AjaxResult.me();
    }



//----------------高级查询--------------------

    @PostMapping("/search")
    public PageList<CourseDoc> search(@RequestParam("queryJson") String queryJson){
        //查询JSON字符串,对象转成查询对象
        NativeSearchQuery nativeSearchQueryBuilder = JSON.parseObject(queryJson, NativeSearchQuery.class);
        //执行查询
        Page<CourseDoc> page = courseDocRepository.search(nativeSearchQueryBuilder);
        //返回结果 ,page转成 PageList
        return new PageList<>(page.getTotalElements() , page.getContent());
    }

    @PostMapping("/searchCourse")
    public PageList<CourseDoc> searchCourse(@RequestBody CourseQuery courseQuery){
        //查询JSON字符串,对象转成查询对象
        NativeSearchQuery nativeSearchQueryBuilder = createCourseQueryForES(courseQuery).build();

        //执行查询
        Page<CourseDoc> page = courseDocRepository.search(nativeSearchQueryBuilder);
        //返回结果 ,page转成 PageList
        return new PageList<>(page.getTotalElements() , page.getContent());
    }


    //拼接查询对象courseQuery -> NativeSearchQueryBuilder
    private NativeSearchQueryBuilder createCourseQueryForES(CourseQuery courseQuery) {
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();


        //添加条件===============================================================================================================
        //组合查询
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        // keyword: "java"  : 查询 MathchQuery  - DSL查询
        if(StringUtils.hasLength(courseQuery.getKeyword())){
            boolQueryBuilder.must(QueryBuilders.matchQuery("name",courseQuery.getKeyword()));
        }

        //过滤
        List<QueryBuilder> filter = boolQueryBuilder.filter();

        //productType: :termQuery
        if(courseQuery.getProductType() != null){
            filter.add(QueryBuilders.termQuery("courseTypeId",courseQuery.getProductType()));
        }

        //priceMax: null : rangeQuery
        if(courseQuery.getPriceMax() != null){
            filter.add(QueryBuilders.rangeQuery("price").lte(courseQuery.getPriceMax()));
        }

        //priceMin: null :rangeQuery
        if(courseQuery.getPriceMin() != null){
            filter.add(QueryBuilders.rangeQuery("price").gte(courseQuery.getPriceMin()));
        }

        nativeSearchQueryBuilder.withQuery(boolQueryBuilder);


        //添加分页
        nativeSearchQueryBuilder.withPageable(PageRequest.of(courseQuery.getPage() - 1,courseQuery.getRows()));


        //添加排序===============================================================================================================
        // sortField:  ; sortType:==
        if(StringUtils.hasLength(courseQuery.getSortField())){

            String sortField = null;
            switch (courseQuery.getSortField().toLowerCase()){
                case "xl": sortField = "buyCount" ; break;
                case "xp": sortField = "onlineDate" ; break;
                case "jg": sortField = "price" ; break;
                case "rq": sortField = "viewCount" ; break;
                case "pl": sortField = "comment" ; break;
                default:sortField = "price" ;
            }

            //排序方式
            SortOrder sortOrder = SortOrder.DESC;
            if(StringUtils.hasLength(courseQuery.getSortType()) && courseQuery.getSortType().toLowerCase().equals("asc")){
                sortOrder = SortOrder.ASC;
            }


            nativeSearchQueryBuilder.withSort(new FieldSortBuilder(sortField).order(sortOrder));
        }

        return nativeSearchQueryBuilder;
    }


}

其他微服务业务调用数据,保存到es

//拷贝数据   要放到es里的数据,拷贝到映射类courseDoc里面,最终保存映射类
BeanUtils.copyProperties(course, courseDoc);
BeanUtils.copyProperties(courseDetail, courseDoc);
BeanUtils.copyProperties(courseMarket, courseDoc);

//保存到es
esFeign.save(courseDoc);

2、feign集成es

2.1 feign接口

//调用目标服务名
@FeignClient(value="es-server",fallbackFactory=EsFeignFactory.class)
public interface EsFeign {

    //保存
    @PostMapping("/es/save")
    AjaxResult save(@RequestBody CourseDoc courseDoc);

    //删除
    @DeleteMapping("/es/delete/{id}")
    AjaxResult del(@PathVariable("id")Long id);

    @PostMapping("/es/search")
    PageList<CourseDoc> search(@RequestParam("queryJson") String queryJson);

    @PostMapping("/es/searchCourse")
    PageList<CourseDoc> searchCourse(@RequestBody CourseQuery courseQuery);

}

2.2 托底数据

@Component
public class EsFeignFactory implements FallbackFactory<EsFeign> {

    // 托底类
    @Override
    public EsFeign create(Throwable throwable) {

        return new EsFeign() {

            //保存失败返回的托底数据
            @Override
            public AjaxResult save(CourseDoc courseDoc) {
                return AjaxResult.me().setSuccess(false).setMessage("保存到es失败");
            }

            @Override
            public AjaxResult del(Long id) {

                return AjaxResult.me().setSuccess(false).setMessage("删除es失败");
            }

            @Override
            public PageList<CourseDoc> search(@RequestParam("queryJson") String queryJson) {
                throwable.printStackTrace();
                return null;
            }

            @Override
            public PageList<CourseDoc> searchCourse(CourseQuery courseQuery) {
                throwable.printStackTrace();
                return new PageList();
            }

        };
    }
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值