赞
踩
接 ElasticSearch服务集群搭建以及应用(三)
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,如下
我们最终的目的是在项目中引用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 } ] } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。