1)在appliction.yml中配置source_field
server:
port: ${port:40100}
spring:
application:
name: xc-search-service
xuecheng:
elasticsearch:
hostlist: ${eshostlist:127.0.0.1:9200} #多个结点中间用逗号分隔
course:
index: xc_course
type: doc
source_field: id,name,grade,mt,st,charge,valid,pic,qq,price,price_old,status,studymodel,teachmode,expires,pub_time,start_time,end_time
4.5 Controlle
@RestController
@RequestMapping("/search/course")
public class EsCourseController implements EsCourseControllerApi {
@Autowired
EsCourseService esCourseService;
@Override
@GetMapping(value="/list/{page}/{size}")
public QueryResponseResult<CoursePub> list(@PathVariable("page") int page,@PathVariable("size") int size, CourseSearchParam courseSearchParam) {
return esCourseService.list(page,size,courseSearchParam);
}
}
4.4 Service
Service方法代码复杂,这里分三步完成。
@Service
public class EsCourseService {
private static final Logger LOGGER = LoggerFactory.getLogger(EsCourseService.class);
@Value("${xuecheng.elasticsearch.course.index}")
private String es_index;
@Value("${xuecheng.elasticsearch.course.type}")
private String es_type;
@Value("${xuecheng.elasticsearch.course.source_field}")
private String source_field;
@Autowired
RestHighLevelClient restHighLevelClient;
public QueryResponseResult<CoursePub> list(int page,int size,CourseSearchParam
courseSearchParam) {
//设置索引
SearchRequest searchRequest = new SearchRequest(es_index);
//设置类型
searchRequest.types(es_type);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//source源字段过虑
String[] source_fields = source_field.split(",");
searchSourceBuilder.fetchSource(source_fields, new String[]{});
//关键字
if(StringUtils.isNotEmpty(courseSearchParam.getKeyword())){
//匹配关键字
MultiMatchQueryBuilder multiMatchQueryBuilder =
QueryBuilders.multiMatchQuery(courseSearchParam.getKeyword(), "name",
"teachplan","description");
//设置匹配占比
multiMatchQueryBuilder.minimumShouldMatch("70%");
//提升另个字段的Boost值
multiMatchQueryBuilder.field("name",10);
boolQueryBuilder.must(multiMatchQueryBuilder);
}
//布尔查询
searchSourceBuilder.query(boolQueryBuilder);
//请求搜索
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = null;
try {
searchResponse = restHighLevelClient.search(searchRequest);
} catch (IOException e) {
e.printStackTrace();
LOGGER.error("xuecheng search error..{}",e.getMessage());
return new QueryResponseResult(CommonCode.SUCCESS,new QueryResult<CoursePub>());
}
//结果集处理
SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits();
//记录总数
long totalHits = hits.getTotalHits();
//数据列表
List<CoursePub> list = new ArrayList<>();
for (SearchHit hit : searchHits) {
CoursePub coursePub = new CoursePub();
//取出source
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
//取出名称
String name = (String) sourceAsMap.get("name");
coursePub.setName(name);
//图片
String pic = (String) sourceAsMap.get("pic");
coursePub.setPic(pic);
//价格
Float price = null;
try {
if(sourceAsMap.get("price")!=null ){
price = Float.parseFloat((String) sourceAsMap.get("price"));
}
} catch (Exception e) {
e.printStackTrace();
}
coursePub.setPrice(price);
Float price_old = null;
try {
if(sourceAsMap.get("price_old")!=null ){
price_old = Float.parseFloat((String) sourceAsMap.get("price_old"));
}
} catch (Exception e) {
e.printStackTrace();
}
coursePub.setPrice_old(price_old);
list.add(coursePub);
}
QueryResult<CoursePub> queryResult = new QueryResult<>();
queryResult.setList(list);
queryResult.setTotal(totalHits);
QueryResponseResult<CoursePub> coursePubQueryResponseResult = new
QueryResponseResult<CoursePub>(CommonCode.SUCCESS,queryResult);
return coursePubQueryResponseResult;
}
}
4.4.2 按分类和难度等级搜索
按分类和难度等级搜索代码如下:
service全部代码如下
@Service
public class EsCourseService {
private static final Logger LOGGER = LoggerFactory.getLogger(EsCourseService.class);
@Value("${xuecheng.elasticsearch.course.index}")
private String es_index;
@Value("${xuecheng.elasticsearch.course.type}")
private String es_type;
@Value("${xuecheng.elasticsearch.course.source_field}")
private String source_field;
@Autowired
RestHighLevelClient restHighLevelClient;
public QueryResponseResult<CoursePub> list(int page,int size,CourseSearchParam
courseSearchParam) {
//设置索引
SearchRequest searchRequest = new SearchRequest(es_index);
//设置类型
searchRequest.types(es_type);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//source源字段过虑
String[] source_fields = source_field.split(",");
searchSourceBuilder.fetchSource(source_fields, new String[]{});
//关键字
if(StringUtils.isNotEmpty(courseSearchParam.getKeyword())){
//匹配关键字
MultiMatchQueryBuilder multiMatchQueryBuilder =
QueryBuilders.multiMatchQuery(courseSearchParam.getKeyword(), "name",
"teachplan","description");
//设置匹配占比
multiMatchQueryBuilder.minimumShouldMatch("70%");
//提升另个字段的Boost值
multiMatchQueryBuilder.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()));
}
//布尔查询
searchSourceBuilder.query(boolQueryBuilder);
//请求搜索
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = null;
try {
searchResponse = restHighLevelClient.search(searchRequest);
} catch (IOException e) {
e.printStackTrace();
LOGGER.error("xuecheng search error..{}",e.getMessage());
return new QueryResponseResult(CommonCode.SUCCESS,new QueryResult<CoursePub>());
}
//结果集处理
SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits();
//记录总数
long totalHits = hits.getTotalHits();
//数据列表
List<CoursePub> list = new ArrayList<>();
for (SearchHit hit : searchHits) {
CoursePub coursePub = new CoursePub();
//取出source
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
//取出名称
String name = (String) sourceAsMap.get("name");
coursePub.setName(name);
//图片
String pic = (String) sourceAsMap.get("pic");
coursePub.setPic(pic);
//价格
Float price = null;
try {
if(sourceAsMap.get("price")!=null ){
price = Float.parseFloat((String) sourceAsMap.get("price"));
}
} catch (Exception e) {
e.printStackTrace();
}
coursePub.setPrice(price);
Float price_old = null;
try {
if(sourceAsMap.get("price_old")!=null ){
price_old = Float.parseFloat((String) sourceAsMap.get("price_old"));
}
} catch (Exception e) {
e.printStackTrace();
}
coursePub.setPrice_old(price_old);
list.add(coursePub);
}
QueryResult<CoursePub> queryResult = new QueryResult<>();
queryResult.setList(list);
queryResult.setTotal(totalHits);
QueryResponseResult<CoursePub> coursePubQueryResponseResult = new
QueryResponseResult<CoursePub>(CommonCode.SUCCESS,queryResult);
return coursePubQueryResponseResult;
}
}
4.4.3 分页与高亮
@Service
public class EsCourseService {
@Value("${xuecheng.course.index}")
private String index;
@Value("${xuecheng.course.type}")
private String type;
@Value("${xuecheng.course.source_field}")
private String source_field;
@Autowired
RestHighLevelClient restHighLevelClient;
//课程搜索
public QueryResponseResult<CoursePub> list(int page, int size, CourseSearchParam courseSearchParam) {
if(courseSearchParam == null){
courseSearchParam = new CourseSearchParam();
}
//创建搜索请求对象
SearchRequest searchRequest = new SearchRequest(index);
//设置搜索类型
searchRequest.types(type);
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);
searchRequest.source(searchSourceBuilder);
QueryResult<CoursePub> queryResult = new QueryResult();
List<CoursePub> list = new ArrayList<>();
try {
//执行搜索
SearchResponse searchResponse = restHighLevelClient.search(searchRequest);
//获取响应结果
SearchHits hits = searchResponse.getHits();
//匹配的总记录数
long totalHits = hits.totalHits;
queryResult.setTotal(totalHits);
SearchHit[] searchHits = hits.getHits();
for(SearchHit hit:searchHits){
CoursePub coursePub = new CoursePub();
//源文档
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
//取出name
String name = (String) sourceAsMap.get("name");
coursePub.setName(name);
//图片
String pic = (String) sourceAsMap.get("pic");
coursePub.setPic(pic);
//价格
Float price = null;
try {
if(sourceAsMap.get("price")!=null ){
price = (Float) sourceAsMap.get("price");
}
} catch (Exception e) {
e.printStackTrace();
}
coursePub.setPrice(price);
//旧价格
Float price_old = null;
try {
if(sourceAsMap.get("price_old")!=null ){
price_old = (Float) 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<CoursePub> queryResponseResult = new QueryResponseResult<CoursePub>(CommonCode.SUCCESS,queryResult);
return queryResponseResult;
}
}
@Value("${xuecheng.course.index}")
private String index;
报错处理
解决方法
启动
启动search服务。启动eurake01和02服务,启动cms2服务。启动
4.5 测试
如果价格用float类型,则运行结果如下:
如果用float类型,就会报这个错误。所以需要改为Double类型