ElasticSearch服务集群搭建以及应用(四)

接 ElasticSearch服务集群搭建以及应用(三)

一:SpringBoot集成ES集群查询设置

1.配置三个ES服务的elasticsearch.yml文件,并启动三个服务
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2.配置logstash下的config目录下配置mysql.conf文件,打开集群配置
在这里插入图片描述
3.logstash的工作是从MySQL中读取数据,向ES中创建索引,这里需要提前创建mapping的模板文件以便logstash 使用。

{
   "mappings" : {
      "es_course" : {
          "properties" : {
            "course_name" : {
               "analyzer" : "ik_max_word",
			   "search_analyzer":"ik_smart",
               "type" : "text"
            },
            "course_description" : {
               "analyzer" : "ik_max_word",
			   "search_analyzer":"ik_smart",
               "type" : "text"
            },
            "id" : {
               "type" : "keyword"
            },
            "course_pic" : {
               "index" : false,
               "type" : "keyword"
            }
         }
      }
   },

   "template" : "es_course"
}

4.使用head新建集群索引es_course,分片3,副本2并使用postman添加映射关系
在这里插入图片描述
5.在logstash的bin目录下,启动logstash
        logstash.bat ‐f …/config/mysql.conf

6.启动成功之后,会看到mysql数据库数据被导入到ES,如下
在这里插入图片描述

二:SpringBoot集成ES集群查询编码

        我们最终的目的是在项目中引用ES的服务 , 实现业务中使用ES索引库实现查询的功能
1.在工程的pom文件里面引入ES相关的jar 6.2.1版本如下:

<!--引入ES-->
<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>6.2.1</version>
</dependency>

<!--引入ES相关API的高级客户端-->
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>6.2.1</version>
</dependency>

<!--引入ES相关API的低级客户端-->
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-client</artifactId>
    <version>6.2.1</version>
</dependency>

2.创建工具类,用来解析ES集群的IP和端口,获取高级客户端对象

@Configuration
public class ESSearchUtil {

    @Value("${elasticsearch.hostlist}")
    private String hostlist;

    /**
     * @description : 获取ES高级客户端对象
     * @Date 2020/11/18
     * @Param []
     * @return org.elasticsearch.client.RestHighLevelClient
     */
    @Bean
    public RestHighLevelClient restHighLevelClient(){
        String[] split = hostlist.split(",");//解析ES集群IP端口信息
        HttpHost[] httpHostArray = new HttpHost[split.length];//创建HttpHost数组,其中存放es主机和端口的配置信息
        for (int i = 0; i < split.length; i++) {
            String item = split[i];
            httpHostArray[i] = new HttpHost(item.split(":")[0], Integer.parseInt(item.split(":")[1]), "http");
        }
        return new RestHighLevelClient(RestClient.builder(httpHostArray));//创建RestHighLevelClient客户端
    }

    /**
     * @description : 获取ES低级客户端对象
     * @Date 2020/11/18
     * @Param []
     * @return org.elasticsearch.client.RestClient
     */
    @Bean
    public RestClient restClient(){
        String[] split = hostlist.split(",");//解析ES集群IP端口信息
        HttpHost[] httpHostArray = new HttpHost[split.length];//创建HttpHost数组,其中存放es主机和端口的配置信息
        for(int i=0;i<split.length;i++){
            String item = split[i];
            httpHostArray[i] = new HttpHost(item.split(":")[0], Integer.parseInt(item.split(":") [1]), "http");
        }
        return RestClient.builder(httpHostArray).build();
    }
}

3.配置application.yml,如下

elasticsearch:
  hostlist: ${eshostlist:127.0.0.1:9200,127.0.0.1:9201,127.0.0.1:9202}
  course:
    index: es_course
    type: doc
    source_field:
      id,course_name,course_description #过滤字段,即不需要查询的字段,我们这里选择保留id,course_name,course_description这几个字段,用逗号隔开

4.创建接口,根据分页参数(page,size)以及对于course_name和course_description进行关键字搜索

@Controller
@RequestMapping("api/es")
public class ESSearchController {

    @Autowired
    private ESService esService;

    /**
     * @description : 按请求的条件从ES索引库中进行分页查询
     * @Date 2020/11/18
     * @Param [page, size, request]
     * @return com.example.common.response.R<com.example.service.es.model.CoursePub>
     */
    @RequestMapping("/list")
    @ResponseBody
    public R list(@RequestBody CourseSearchRequest request){
        Page<CoursePub> pubPage = esService.list(request);
        if(pubPage!=null){
            return R.ok(pubPage);
        }
        return R.error("未获取到相关数据");
    }
}
@Data
public class CourseSearchRequest {
    private Integer page;//页码
    private Integer size;//每页条数
    private String keyword;//按关键字查询
}

5.实现类中具体实现的代码如下:

@Service
@Slf4j
public class ESServiceImpl implements ESService {

    @Value("${elasticsearch.course.index}")
    private String index;

    @Value("${elasticsearch.course.type}")
    private String type;

    @Value("${elasticsearch.course.source_field}")
    private String source_field;

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    /**
     * @description :  按请求的条件从ES索引库中进行分页查询
     * @Date 2020/11/18
     * @Param [page, size, request]
     * @return com.example.common.page.Page<com.example.service.es.model.CoursePub>
     */
    public Page<CoursePub> list(CourseSearchRequest request){
        Page<CoursePub> pubPage=new Page<>();

        SearchRequest searchRequest=new SearchRequest(index);//创建搜索请求对象,括号里给索引库名称
        searchRequest.types(type);//设置索引库的类型

        SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();

        //创建布尔查询字段
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        //source_field字段过滤
        String[] source_field_array = source_field.split(",");
        searchSourceBuilder.fetchSource(source_field_array,new String[]{});

        //关键字查询,按"course_name", "course_description"两个字段进行关键字的索引
        if(!StringUtil.isEmptyString(request.getKeyword())){
            MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(request.getKeyword(), "course_name", "course_description");
            multiMatchQueryBuilder.minimumShouldMatch("70%");//设置匹配占比70%
            multiMatchQueryBuilder.field("course_name",10);//course_name字段匹配度比其他字段高10倍
            boolQueryBuilder.must(multiMatchQueryBuilder);
        }

        //分页
        int page=request.getPage();
        int size=request.getSize();
        if(page<=0){ page = 1; }
        if(size<=0){ size = 20; }
        int start = (page-1)*size;
        searchSourceBuilder.from(start);
        searchSourceBuilder.size(size);

        //设置布尔查询boolQueryBuilder到searchSourceBuilder
        searchSourceBuilder.query(boolQueryBuilder);
        searchRequest.source(searchSourceBuilder);

        SearchResponse response=null;
        try {
            //执行搜索
            response = restHighLevelClient.search(searchRequest);
        } catch (IOException e) {
            e.printStackTrace();
            log.info("查询数据有误...");
            return pubPage;
        }

        //获取响应结果
        SearchHits hits = response.getHits();
        pubPage.setCurrentPage(page);//当前页码
        pubPage.setPageSize(size);//页面大小
        pubPage.setTotal(hits.getTotalHits());//总记录数

        List<CoursePub> list=new ArrayList<>();
        SearchHit[] searchHits = hits.getHits();
        for (SearchHit hit : searchHits) {
            CoursePub pub=new CoursePub();
            Map<String, Object> map = hit.getSourceAsMap();
            String id = (String) map.get("id");//获取id
            String courseName= (String) map.get("course_name");
            String courseDescription= (String) map.get("course_description");
            pub.setId(id);
            pub.setCourseName(courseName);
            pub.setCourseDescription(courseDescription);
            list.add(pub);
        }
        pubPage.setList(list);
        return pubPage;
    }
}

6.接口测试请求如下

{
    "code": "0000",
    "msg": "成功",
    "data": {
        "currentPage": 1,
        "pageSize": 10,
        "pages": 0,
        "total": 6,
        "list": [
            {
                "id": "1",
                "courseName": "JAVA基础",
                "courseDescription": "JAVA基础是学好JAVA语言的核心,面向对象,多线程等",
                "courseTime": null,
                "coursePic": null
            },
            {
                "id": "4",
                "courseName": "JAVA单列集合",
                "courseDescription": "JAVA单列集合包括list接口和set接口,底下分别有实现类",
                "courseTime": null,
                "coursePic": null
            },
            {
                "id": "5",
                "courseName": "JAVA双列集合",
                "courseDescription": "JAVA双列集合包括map接口,底下分别有实现类",
                "courseTime": null,
                "coursePic": null
            },
            {
                "id": "6",
                "courseName": "JAVA数据结构",
                "courseDescription": "数据结构包含栈,队列,数组,链表,红黑树",
                "courseTime": null,
                "coursePic": null
            },
            {
                "id": "8",
                "courseName": "JAVA面向对象三大特性",
                "courseDescription": "封装 继承 多态",
                "courseTime": null,
                "coursePic": null
            },
            {
                "id": "9",
                "courseName": "JAVA常用的设计模式",
                "courseDescription": "单例模式:就是将构造方法私有化,分为直接加载和懒加载\r\n\t工厂模式:分为简单工厂模式(根据传递的参数创建指定对象),工厂方法模式(在方法里面创建对象),抽象工厂(接口中定义不同的抽象方法创建对象)模式\r\n\t观察者模式:就是发布订阅模式,订阅即可收到消息,如activeMQ的消息队列\r\n\t代理模式:通过代理对象访问目标对象,如动态代理技术",
                "courseTime": null,
                "coursePic": null
            }
        ]
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值