diff --git a/pom.xml b/pom.xml index 039b993771a00932334b8f675704b37fe98ca4ec..d8e528ce863da5b212255a8fdf26a002ea132999 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ org.elasticsearch.client elasticsearch-rest-high-level-client - 7.3.0 + 7.12.0 org.elasticsearch @@ -26,7 +26,7 @@ org.elasticsearch elasticsearch - 7.3.0 + 7.12.0 org.springframework.boot @@ -39,15 +39,30 @@ test 2.0.6.RELEASE + + org.elasticsearch.plugin + x-pack-sql-jdbc + 7.3.0 + + + org.springframework.boot + spring-boot-starter-web + 2.0.1.RELEASE + org.projectlombok lombok 1.16.10 - org.elasticsearch.plugin - x-pack-sql-jdbc - 7.3.0 + org.apache.commons + commons-io + 1.3.2 + + + org.apache.commons + commons-lang3 + 3.1 diff --git a/src/main/java/com/kwan/shuyu/SearchApplication.java b/src/main/java/com/kwan/shuyu/SearchApplication.java index deed20fc0578a5e2e12b11abb23f842ff8789cc3..aa91492e6105e4c27b9ec3a0cc9e2875e8745f6d 100644 --- a/src/main/java/com/kwan/shuyu/SearchApplication.java +++ b/src/main/java/com/kwan/shuyu/SearchApplication.java @@ -3,10 +3,9 @@ package com.kwan.shuyu; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; - @SpringBootApplication public class SearchApplication { public static void main(String[] args) { - SpringApplication.run(SearchApplication.class,args); + SpringApplication.run(SearchApplication.class, args); } } diff --git a/src/main/java/com/kwan/shuyu/controller/EsCourseController.java b/src/main/java/com/kwan/shuyu/controller/EsCourseController.java new file mode 100644 index 0000000000000000000000000000000000000000..ddb75efb3a00adec537021e7fbc7d145079a8db9 --- /dev/null +++ b/src/main/java/com/kwan/shuyu/controller/EsCourseController.java @@ -0,0 +1,25 @@ +package com.kwan.shuyu.controller; + +import com.kwan.shuyu.domain.CoursePub; +import com.kwan.shuyu.domain.CourseSearchParam; +import com.kwan.shuyu.domain.QueryResponseResult; +import com.kwan.shuyu.service.EsCourseServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/search/course") +public class EsCourseController { + + @Autowired + private EsCourseServiceImpl esCourseServiceImpl; + + @GetMapping(value = "/list/{page}/{size}") + public QueryResponseResult list(@PathVariable("page") int page + , @PathVariable("size") int size, CourseSearchParam courseSearchParam) { + return esCourseServiceImpl.list(page, size, courseSearchParam); + } +} \ No newline at end of file diff --git a/src/main/java/com/kwan/shuyu/domain/CommonCode.java b/src/main/java/com/kwan/shuyu/domain/CommonCode.java new file mode 100644 index 0000000000000000000000000000000000000000..57f7e991252af6ebe6d9a25c0af39d3c45bbc731 --- /dev/null +++ b/src/main/java/com/kwan/shuyu/domain/CommonCode.java @@ -0,0 +1,53 @@ +package com.kwan.shuyu.domain; + + +import lombok.ToString; + +/** + * @author : qinyingjie + * @version : 2.2.0 + * @date : 2023/5/13 22:20 + */ +@ToString +public enum CommonCode implements ResultCode { + INVALID_PARAM(false, 10003, "非法参数!"), + SUCCESS(true, 10000, "操作成功!"), + FAIL(false, 11111, "操作失败!"), + UNAUTHENTICATED(false, 10001, "此操作需要登陆系统!"), + UNAUTHORISE(false, 10002, "权限不足,无权操作!"), + SERVER_ERROR(false, 99999, "抱歉,系统繁忙,请稍后重试!"); + /** + * 操作是否成功 + */ + boolean success; + /** + * 操作代码 + */ + int code; + /** + * 提示信息 + */ + String message; + + private CommonCode(boolean success, int code, String message) { + this.success = success; + this.code = code; + this.message = message; + } + + + @Override + public boolean success() { + return success; + } + + @Override + public int code() { + return code; + } + + @Override + public String message() { + return message; + } +} diff --git a/src/main/java/com/kwan/shuyu/domain/CoursePub.java b/src/main/java/com/kwan/shuyu/domain/CoursePub.java new file mode 100644 index 0000000000000000000000000000000000000000..b021814dc6d77ee984341796c26ba05fc36ba9d4 --- /dev/null +++ b/src/main/java/com/kwan/shuyu/domain/CoursePub.java @@ -0,0 +1,44 @@ +package com.kwan.shuyu.domain; + +import lombok.Data; +import lombok.ToString; + +import java.io.Serializable; +import java.util.Date; + +@Data +@ToString +public class CoursePub implements Serializable { + private static final long serialVersionUID = -916357110051689487L; + private String id; + private String name; + private String users; + private String mt; + private String st; + private String grade; + private String studymodel; + private String teachmode; + private String description; + /** + * 图片 + */ + private String pic; + /** + * 时间戳 + */ + private Date timestamp; + private String charge; + private String valid; + private String qq; + private Double price; + private Double price_old; + private String expires; + /** + * 课程计划 + */ + private String teachplan; + /** + * 课程发布时间 + */ + private String pubTime; +} \ No newline at end of file diff --git a/src/main/java/com/kwan/shuyu/domain/CourseSearchParam.java b/src/main/java/com/kwan/shuyu/domain/CourseSearchParam.java new file mode 100644 index 0000000000000000000000000000000000000000..d6d72f529c08110f70a41acb8ce2d1d80e253226 --- /dev/null +++ b/src/main/java/com/kwan/shuyu/domain/CourseSearchParam.java @@ -0,0 +1,38 @@ +package com.kwan.shuyu.domain; + +import lombok.Data; +import lombok.ToString; + +@Data +@ToString +public class CourseSearchParam { + /** + * 关键字 + */ + String keyword; + /** + * 一级分类 + */ + String mt; + /** + * 二级分类 + */ + String st; + /** + * 难度等级 + */ + String grade; + /** + * 价格区间 + */ + Float price_min; + Float price_max; + /** + * 排序字段 + */ + String sort; + /** + * 过虑字段 + */ + String filter; +} \ No newline at end of file diff --git a/src/main/java/com/kwan/shuyu/domain/QueryResponseResult.java b/src/main/java/com/kwan/shuyu/domain/QueryResponseResult.java new file mode 100644 index 0000000000000000000000000000000000000000..bebdf117b4d18e88525fd5cba4d0f9f2ccb96259 --- /dev/null +++ b/src/main/java/com/kwan/shuyu/domain/QueryResponseResult.java @@ -0,0 +1,16 @@ +package com.kwan.shuyu.domain; + +import lombok.Data; +import lombok.ToString; + +@Data +@ToString +public class QueryResponseResult extends ResponseResult { + + QueryResult queryResult; + + public QueryResponseResult(ResultCode resultCode, QueryResult queryResult) { + super(resultCode); + this.queryResult = queryResult; + } +} \ No newline at end of file diff --git a/src/main/java/com/kwan/shuyu/domain/QueryResult.java b/src/main/java/com/kwan/shuyu/domain/QueryResult.java new file mode 100644 index 0000000000000000000000000000000000000000..97786e560a75368eb0cedf95fa53de911bcbc5ab --- /dev/null +++ b/src/main/java/com/kwan/shuyu/domain/QueryResult.java @@ -0,0 +1,20 @@ +package com.kwan.shuyu.domain; + +import lombok.Data; +import lombok.ToString; + +import java.util.List; + + +@Data +@ToString +public class QueryResult { + /** + * 数据列表 + */ + private List list; + /** + * 数据总数 + */ + private long total; +} diff --git a/src/main/java/com/kwan/shuyu/domain/Response.java b/src/main/java/com/kwan/shuyu/domain/Response.java new file mode 100644 index 0000000000000000000000000000000000000000..9f5f96ef9fa738e8d8715f0960030bf4405b699f --- /dev/null +++ b/src/main/java/com/kwan/shuyu/domain/Response.java @@ -0,0 +1,7 @@ +package com.kwan.shuyu.domain; + + +public interface Response { + public static final boolean SUCCESS = true; + public static final int SUCCESS_CODE = 10000; +} diff --git a/src/main/java/com/kwan/shuyu/domain/ResponseResult.java b/src/main/java/com/kwan/shuyu/domain/ResponseResult.java new file mode 100644 index 0000000000000000000000000000000000000000..aaca9006fdd1ea06e57040f93a3e5a165ec159a2 --- /dev/null +++ b/src/main/java/com/kwan/shuyu/domain/ResponseResult.java @@ -0,0 +1,33 @@ +package com.kwan.shuyu.domain; + +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; + + +@Data +@ToString +@NoArgsConstructor +public class ResponseResult implements Response { + + /** + * 操作是否成功 + */ + boolean success = SUCCESS; + + /** + * 操作代码 + */ + int code = SUCCESS_CODE; + + /** + * 提示信息 + */ + String message; + + public ResponseResult(ResultCode resultCode) { + this.success = resultCode.success(); + this.code = resultCode.code(); + this.message = resultCode.message(); + } +} diff --git a/src/main/java/com/kwan/shuyu/domain/ResultCode.java b/src/main/java/com/kwan/shuyu/domain/ResultCode.java new file mode 100644 index 0000000000000000000000000000000000000000..7c7ecd5f98437c27d9dfc6b0c3a1594dfcca84e3 --- /dev/null +++ b/src/main/java/com/kwan/shuyu/domain/ResultCode.java @@ -0,0 +1,19 @@ +package com.kwan.shuyu.domain; + + +public interface ResultCode { + /** + * 操作是否成功,true为成功,false操作失败 + */ + boolean success(); + + /** + * 操作代码 + */ + int code(); + + /** + * 提示信息 + */ + String message(); +} diff --git a/src/main/java/com/kwan/shuyu/service/EsCourseServiceImpl.java b/src/main/java/com/kwan/shuyu/service/EsCourseServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..f6df4256627cf2f00814209efc185843afb82694 --- /dev/null +++ b/src/main/java/com/kwan/shuyu/service/EsCourseServiceImpl.java @@ -0,0 +1,168 @@ +package com.kwan.shuyu.service; + +import com.kwan.shuyu.domain.*; +import com.kwan.shuyu.service.impl.EsCourseService; +import org.apache.commons.lang3.StringUtils; +import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.client.RequestOptions; +import org.elasticsearch.client.RestHighLevelClient; +import org.elasticsearch.common.text.Text; +import org.elasticsearch.index.query.BoolQueryBuilder; +import org.elasticsearch.index.query.MultiMatchQueryBuilder; +import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.search.SearchHit; +import org.elasticsearch.search.SearchHits; +import org.elasticsearch.search.builder.SearchSourceBuilder; +import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; +import org.elasticsearch.search.fetch.subphase.highlight.HighlightField; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + + +@Service +public class EsCourseServiceImpl implements EsCourseService { + + @Value("${kwan.course.source_field}") + private String source_field; + @Autowired + private RestHighLevelClient restHighLevelClient; + + /** + * 课程搜索 + * + * @param page + * @param size + * @param courseSearchParam + * @return + */ + @Override + public QueryResponseResult list(int page, int size, CourseSearchParam courseSearchParam) { + if (courseSearchParam == null) { + courseSearchParam = new CourseSearchParam(); + } + //1创建搜索请求对象 + SearchRequest searchRequest = new SearchRequest("xc_course"); + SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); + //过虑源字段 + String[] source_field_array = source_field.split(","); + searchSourceBuilder.fetchSource(source_field_array, new String[]{}); + //创建布尔查询对象 + BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); + //搜索条件 + //根据关键字搜索 + if (StringUtils.isNotEmpty(courseSearchParam.getKeyword())) { + MultiMatchQueryBuilder multiMatchQueryBuilder = + QueryBuilders + .multiMatchQuery(courseSearchParam.getKeyword(), "name", "description", "teachplan") + .minimumShouldMatch("70%") + .field("name", 10); + boolQueryBuilder.must(multiMatchQueryBuilder); + } + if (StringUtils.isNotEmpty(courseSearchParam.getMt())) { + //根据一级分类 + boolQueryBuilder.filter(QueryBuilders.termQuery("mt", courseSearchParam.getMt())); + } + if (StringUtils.isNotEmpty(courseSearchParam.getSt())) { + //根据二级分类 + boolQueryBuilder.filter(QueryBuilders.termQuery("st", courseSearchParam.getSt())); + } + if (StringUtils.isNotEmpty(courseSearchParam.getGrade())) { + //根据难度等级 + boolQueryBuilder.filter(QueryBuilders.termQuery("grade", courseSearchParam.getGrade())); + } + //设置boolQueryBuilder到searchSourceBuilder + searchSourceBuilder.query(boolQueryBuilder); + //设置分页参数 + if (page <= 0) { + page = 1; + } + if (size <= 0) { + size = 12; + } + //起始记录下标 + int from = (page - 1) * size; + searchSourceBuilder.from(from); + searchSourceBuilder.size(size); + //设置高亮 + HighlightBuilder highlightBuilder = new HighlightBuilder(); + highlightBuilder.preTags(""); + highlightBuilder.postTags(""); + //设置高亮字段 + highlightBuilder.fields().add(new HighlightBuilder.Field("name")); + searchSourceBuilder.highlighter(highlightBuilder); + searchRequest.source(searchSourceBuilder); + QueryResult queryResult = new QueryResult(); + List list = new ArrayList<>(); + try { + //2执行搜索 + SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT); + //3获取响应结果 + SearchHits hits = searchResponse.getHits(); + long totalHits = hits.getTotalHits().value; + //匹配的总记录数 + queryResult.setTotal(totalHits); + SearchHit[] searchHits = hits.getHits(); + for (SearchHit hit : searchHits) { + CoursePub coursePub = new CoursePub(); + //源文档 + Map sourceAsMap = hit.getSourceAsMap(); + //取出id + String id = (String) sourceAsMap.get("id"); + coursePub.setId(id); + //取出name + String name = (String) sourceAsMap.get("name"); + //取出高亮字段name + Map highlightFields = hit.getHighlightFields(); + if (highlightFields != null) { + HighlightField highlightFieldName = highlightFields.get("name"); + if (highlightFieldName != null) { + Text[] fragments = highlightFieldName.fragments(); + StringBuffer stringBuffer = new StringBuffer(); + for (Text text : fragments) { + stringBuffer.append(text); + } + name = stringBuffer.toString(); + } + } + coursePub.setName(name); + //图片 + String pic = (String) sourceAsMap.get("pic"); + coursePub.setPic(pic); + //价格 + Double price = null; + try { + if (sourceAsMap.get("price") != null) { + price = (Double) sourceAsMap.get("price"); + } + } catch (Exception e) { + e.printStackTrace(); + } + coursePub.setPrice(price); + //旧价格 + Double price_old = null; + try { + if (sourceAsMap.get("price_old") != null) { + price_old = (Double) sourceAsMap.get("price_old"); + } + } catch (Exception e) { + e.printStackTrace(); + } + coursePub.setPrice_old(price_old); + //将coursePub对象放入list + list.add(coursePub); + } + } catch (IOException e) { + e.printStackTrace(); + } + queryResult.setList(list); + QueryResponseResult queryResponseResult = new QueryResponseResult<>(CommonCode.SUCCESS, queryResult); + return queryResponseResult; + } +} \ No newline at end of file diff --git a/src/main/java/com/kwan/shuyu/service/impl/EsCourseService.java b/src/main/java/com/kwan/shuyu/service/impl/EsCourseService.java new file mode 100644 index 0000000000000000000000000000000000000000..a4816e6f4094e44e2804a3d6e5b2a0d40148768c --- /dev/null +++ b/src/main/java/com/kwan/shuyu/service/impl/EsCourseService.java @@ -0,0 +1,19 @@ +package com.kwan.shuyu.service.impl; + +import com.kwan.shuyu.domain.CoursePub; +import com.kwan.shuyu.domain.CourseSearchParam; +import com.kwan.shuyu.domain.QueryResponseResult; + + +public interface EsCourseService { + + /** + * 查询课程 + * + * @param page + * @param size + * @param courseSearchParam + * @return + */ + QueryResponseResult list(int page, int size, CourseSearchParam courseSearchParam); +} \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 4c8948d4a341debddd0845a3fc12affe816bd553..22f010da5d93d4d9122672454d2c2c1ed9cfa470 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -6,4 +6,6 @@ spring: name: search-service kwan: elasticsearch: - hostlist: 47.119.160.231:9200 #多个节点用逗号分隔 \ No newline at end of file + hostlist: 47.119.160.231:9200 #多个节点用逗号分隔 + course: #课程字段 + source_field: id,name,grade,mt,st,charge,valid,pic,qq,price,price_old,status,studymodel,teachmode,expires,pub_time,start_time,end_time \ No newline at end of file diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml index f3bbecbefc49cee675306491a55209b08759f2ca..1799e05cbed6390f52ade41f7d497b9337c26776 100644 --- a/src/main/resources/logback-spring.xml +++ b/src/main/resources/logback-spring.xml @@ -1,9 +1,7 @@ - - @@ -12,7 +10,6 @@ utf8 - @@ -23,7 +20,6 @@ %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - @@ -33,8 +29,6 @@ - - diff --git a/src/test/java/es_06_log/TestLog.java b/src/test/java/es_06_log/TestLog.java new file mode 100644 index 0000000000000000000000000000000000000000..cdca49e43f1b9864b446c8ce857f2b88de01a910 --- /dev/null +++ b/src/test/java/es_06_log/TestLog.java @@ -0,0 +1,37 @@ +package es_06_log; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.Random; + +/** + * 测试ELK查看log + * + * @author : qinyingjie + * @version : 2.2.0 + * @date : 2023/5/13 22:14 + */ +@SpringBootTest +@RunWith(SpringRunner.class) +public class TestLog { + private static final Logger LOGGER = LoggerFactory.getLogger(TestLog.class); + + @Test + public void testLog() { + Random random = new Random(); + while (true) { + int userid = random.nextInt(10); + LOGGER.info("userId:{},send:{}", userid, "hello world.I am " + userid); + try { + Thread.sleep(500); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } +} \ No newline at end of file