'pageadd'

This commit is contained in:
joshen@zcwytd.com
2023-06-07 23:10:14 +08:00
parent f6176078ae
commit f9685a9094
1186 changed files with 129272 additions and 0 deletions

View File

@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.xboe</groupId>
<artifactId>module</artifactId>
<version>1.0.0</version>
<!--<relativePath>../..</relativePath> -->
</parent>
<artifactId>xboe-module-es</artifactId>
<name>xboe-module-es</name>
<packaging>jar</packaging>
<description>ES的处理包装</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.xboe</groupId>
<artifactId>xboe-core</artifactId>
</dependency>
<dependency>
<groupId>com.xboe</groupId>
<artifactId>xboe-module-course</artifactId>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.9.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.9.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.9.0</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- 以下几项和jdk有关 -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-parameter-names</artifactId>
</dependency>
<!-- log -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,752 @@
package com.xboe.module.elasticsearc;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.replication.ReplicationResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
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.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xboe.common.PageList;
import com.xboe.module.course.dto.CourseFullText;
import com.xboe.module.course.service.ICourseFullTextSearch;
import lombok.extern.slf4j.Slf4j;
/**
* 课程内容全文检索的实现
*
*/
@Slf4j
@Service
public class CourseElasticsearchImpl implements ICourseFullTextSearch{
@Resource
private RestHighLevelClient restHighLevelClient;
@Resource
ElasticsearchUtil esUtil;
/**
* 创建新的索引
* @param indexName
* @return
*/
@Override
public boolean reCreateIndex(String indexName) throws Exception{
boolean isExists = esUtil.isIndexExists(indexName);
if(!isExists) {
boolean ok =createIndex(indexName);
if(!ok) {
log.error("创建索引【"+indexName+"】失败");
return false;
}
}
return true;
}
/**
* 创建索引
* @param name
* @return
* @throws Exception
*/
public boolean createIndex(String name) throws Exception{
XContentBuilder settingBuilder= XContentFactory.jsonBuilder();
settingBuilder.startObject();
settingBuilder.field("index").startObject().field("number_of_replicas",5).endObject();
settingBuilder.field("analysis").startObject()
.field("analyzer").startObject()
.field("comma").startObject()
.field("type","pattern")
.field("pattern",",")
.endObject()
.endObject()
.endObject();
settingBuilder.endObject();
XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject();
builder.field("properties").startObject();
builder.field("id").startObject().field("index", "true").field("type", "keyword").endObject();
//builder.field("name").startObject().field("type", "text").field("analyzer", "ik_max_word").field("search_analyzer","ik_smart").endObject();
builder.field("name").startObject().field("type", "keyword").endObject();
builder.field("keywords").startObject().field("type", "text").field("analyzer", "ik_max_word").field("search_analyzer","ik_smart").endObject();
builder.field("type").startObject().field("type", "integer").endObject();
builder.field("source").startObject().field("type", "integer").endObject();
builder.field("summary").startObject().field("type", "text").field("analyzer", "ik_max_word").field("search_analyzer","ik_smart").endObject();
builder.field("companyId").startObject().field("type", "keyword").endObject();
builder.field("coverImg").startObject().field("type", "keyword").endObject();
builder.field("score").startObject().field("type", "keyword").endObject();
builder.field("studies").startObject().field("type", "integer").endObject();
builder.field("teacher").startObject().field("type", "text").field("analyzer","comma").endObject();
builder.field("teacherCode").startObject().field("type", "text").field("analyzer","comma").endObject();
builder.field("publishTime").startObject().field("type", "integer").endObject();
builder.field("startTime").startObject().field("type", "integer").endObject();
builder.field("endTime").startObject().field("type", "integer").endObject();
builder.field("duration").startObject().field("type", "integer").endObject();
builder.field("tags").startObject().field("type", "text").endObject();
builder.field("sysType1").startObject().field("type", "keyword").endObject();
builder.field("sysType2").startObject().field("type", "keyword").endObject();
builder.field("sysType3").startObject().field("type", "keyword").endObject();
builder.field("isTop").startObject().field("type", "integer").endObject();
builder.field("topTime").startObject().field("type", "integer").endObject();
builder.field("resOwner").startObject().field("type", "keyword").endObject();
builder.field("isSetAudience").startObject().field("type", "keyword").endObject();
builder.field("createdAt").startObject().field("type", "integer").endObject();
builder.field("openCourse").startObject().field("type", "integer").endObject();
//builder.field("audience").startObject().field("type", "text").field("analyzer","comma").endObject();
builder.field("audiences").startObject().field("type", "keyword").endObject();
builder.field("device").startObject().field("type", "integer").endObject();
builder.field("openEnroll").startObject().field("type", "integer").endObject();
builder.endObject();
builder.endObject();
CreateIndexRequest createIndexRequest = new CreateIndexRequest(name);
createIndexRequest.settings(settingBuilder);
createIndexRequest.mapping(builder);
CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
boolean acknowledged = createIndexResponse.isAcknowledged();
if (acknowledged) {
return true;
} else {
return false;
}
}
@Override
public String publish(String indexName, CourseFullText cf) throws Exception{
boolean isExists = esUtil.isIndexExists(indexName);
if(!isExists) {
boolean ok =createIndex(indexName);
if(!ok) {
log.error("创建索引【"+indexName+"】失败");
return null;
}
}
if(cf.getOpenEnroll()==null) {
cf.setOpenEnroll(0);
}
//检查是否已存在
IndexRequest indexRequest = new IndexRequest(indexName);
ObjectMapper mapper=new ObjectMapper();
String textJson =mapper.writeValueAsString(cf);
indexRequest.source(textJson, XContentType.JSON);
IndexResponse indexResponse = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
if (indexResponse != null) {
String id = indexResponse.getId();
String index = indexResponse.getIndex();
long version = indexResponse.getVersion();
if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
log.info("新增全文索引文档成功! " + index + "-" + id + "-" + version);
return id;
} else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
log.info("修改文档成功!");
return id;
}
// 分片处理信息
ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo();
if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
log.info("分片处理信息.....");
}
// 如果有分片副本失败,可以获得失败原因信息
if (shardInfo.getFailed() > 0) {
for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
String reason = failure.reason();
log.info("副本失败原因:" + reason);
}
}
}
return null;
}
@Override
public boolean checkHas(String indexName,String id) {
GetRequest getRequest=new GetRequest(indexName,id);
try {
boolean exists = restHighLevelClient.exists(getRequest, RequestOptions.DEFAULT);
return exists;
} catch (IOException e) {
log.info("检查文档是否存在错误",e);
}
return false;
}
@Override
public String republish(String indexName, CourseFullText item, String fullTextId) throws Exception{
boolean isExists = esUtil.isIndexExists(indexName);
if(!isExists) {
boolean ok =createIndex(indexName);
if(!ok) {
log.error("创建索引【"+indexName+"】失败");
return null;
}
}
String fullId=fullTextId;
if(item.getOpenEnroll()==null) {
item.setOpenEnroll(0);
}
boolean exists=false;
if(StringUtils.isNotBlank(fullTextId)) {
GetRequest getRequest=new GetRequest(indexName,fullTextId);
exists = restHighLevelClient.exists(getRequest, RequestOptions.DEFAULT);
}
//System.out.println(item.getName()+"="+item.getType());
if(exists) {
UpdateRequest updateRequest = new UpdateRequest(indexName, fullTextId);
ObjectMapper mapper=new ObjectMapper();
String textJson =mapper.writeValueAsString(item);
updateRequest.doc(textJson, XContentType.JSON);
UpdateResponse updateResponse = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
int ok=updateResponse.status().getStatus();
if (ok==200) {
log.info("更新【"+fullTextId+"】成功!");
} else {
log.error("更新【"+fullTextId+"】失败",updateResponse);
}
}else {
fullId=publish(indexName,item);
}
return fullId;
}
@Override
public void updateField(String indexName, String field,Object value, String fullTextId) throws Exception{
UpdateRequest updateRequest = new UpdateRequest(indexName, fullTextId);
ObjectMapper mapper=new ObjectMapper();
Map<String,Object> map=new HashMap<String,Object>();
map.put(field, value);
String textJson =mapper.writeValueAsString(map);
updateRequest.doc(textJson, XContentType.JSON);
UpdateResponse updateResponse = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
if (updateResponse.getResult() == DocWriteResponse.Result.UPDATED) {
log.info("更新【"+fullTextId+"】成功!");
} else {
log.error("更新【"+fullTextId+"】失败");
}
}
private BoolQueryBuilder createQuery(CourseFullText params) {
BoolQueryBuilder boolQuery= QueryBuilders.boolQuery();
if(params.getType()!=null) {
if(params.getType()==20) {
RangeQueryBuilder typeQuery = QueryBuilders.rangeQuery("type");
typeQuery.lte(20);
boolQuery.filter(typeQuery);
}else {
boolQuery.filter(QueryBuilders.termQuery("type", params.getType()));
}
}else if(StringUtils.isNotBlank(params.getTypes())) {
List<Integer> typeList=new ArrayList<>();
if(params.getTypes().indexOf("20")>-1) {
typeList.add(10);
}
String[] typeArray=params.getTypes().split("-");
for(String s:typeArray) {
typeList.add(Integer.valueOf(s));
}
boolQuery.filter(QueryBuilders.termsQuery("type", typeList));
}
if(params.getSource()!=null) {
boolQuery.filter(QueryBuilders.termQuery("source", params.getSource()));
}
if(params.getOpenCourse()!=null && params.getOpenCourse()==1) {
boolQuery.filter(QueryBuilders.termQuery("openCourse", params.getOpenCourse()));
}
if(StringUtils.isNotBlank(params.getSysType1())) {
if(params.getSysType1().indexOf("-")>-1) {
String[] typeArray=params.getSysType1().split("-");
boolQuery.filter(QueryBuilders.termsQuery("sysType1", typeArray));
}else {
boolQuery.filter(QueryBuilders.termQuery("sysType1", params.getSysType1()));
}
}
if(StringUtils.isNotBlank(params.getSysType2())) {
if(params.getSysType2().indexOf("-")>-1) {
String[] typeArray=params.getSysType2().split("-");
boolQuery.filter(QueryBuilders.termsQuery("sysType2", typeArray));
}else {
boolQuery.filter(QueryBuilders.termQuery("sysType2", params.getSysType2()));
}
}
if(StringUtils.isNotBlank(params.getSysType3())) {
if(params.getSysType3().indexOf("-")>-1) {
String[] typeArray=params.getSysType3().split("-");
boolQuery.filter(QueryBuilders.termsQuery("sysType3", typeArray));
}else {
boolQuery.filter(QueryBuilders.termQuery("sysType3", params.getSysType3()));
}
}
//增加companyId过滤
if(StringUtils.isNotBlank(params.getCompanyId())) {
BoolQueryBuilder companyFilter= QueryBuilders.boolQuery();
companyFilter.should(QueryBuilders.termQuery("source",2));//新系统的数据
BoolQueryBuilder old= QueryBuilders.boolQuery();
old.must(QueryBuilders.termQuery("source",1));//必须是老系统的数据
old.must(QueryBuilders.termQuery("companyId",params.getCompanyId()));//必须是老系统的数据
companyFilter.should(old);
companyFilter.minimumShouldMatch(1);
boolQuery.filter(companyFilter);
}
//加上Source判断是为了应对后台查询后台查询时不需要权限但是需要指定数据来源
if(params.getSource()==null || params.getSource()==0 ) {
//受众权限条件,必须是有受众的课程并且受众条件不为空
if(params.getAudiences()!=null && params.getAudiences().length>0) {
//if(StringUtils.isNotBlank(params.getAudience())) {
BoolQueryBuilder audience= QueryBuilders.boolQuery();
audience.should(QueryBuilders.termQuery("isSetAudience",0));
BoolQueryBuilder has= QueryBuilders.boolQuery();
//String[] ids=params.getAudience().split(",");
has.must(QueryBuilders.termQuery("isSetAudience",1));
//has.must(QueryBuilders.termsQuery("audience", ids));
has.must(QueryBuilders.termsQuery("audiences", params.getAudiences()));
audience.should(has);
audience.minimumShouldMatch(1);
boolQuery.filter(audience);
//log.error("audience="+audience.toString());
}else {
//如果当前用户无受众,只能查询未设置受众的课程
boolQuery.must(QueryBuilders.termQuery("isSetAudience",0));
}
}
//在哪端显示
if(params.getDevice()!=null) {
BoolQueryBuilder deviceQuery = QueryBuilders.boolQuery();
if(params.getDevice()==1) { //pc端可见的课程以及又端都可见的课程
deviceQuery.should(QueryBuilders.termQuery("device", 1));
deviceQuery.should(QueryBuilders.termQuery("device", 3));
}else if(params.getDevice()==2) { //移动端可见的课程
deviceQuery.should(QueryBuilders.termQuery("device", 2));
deviceQuery.should(QueryBuilders.termQuery("device", 3));
}
if(deviceQuery.hasClauses()) {
boolQuery.must(deviceQuery);
}
}
if(StringUtils.isNotBlank(params.getKeywords())) {
String words=QueryParser.escape(params.getKeywords());
// System.out.println(params.getKeywords());
// System.out.println(words);
BoolQueryBuilder keywordQuery = QueryBuilders.boolQuery();
keywordQuery.should(QueryBuilders.wildcardQuery("name", "*"+words+"*").boost(9f));
keywordQuery.should(QueryBuilders.wildcardQuery("teacher", "*"+words+"*").boost(7f));
//keywordQuery.should(QueryBuilders.queryStringQuery(words).field("name", 9f));//用此方法无法查询出有转义符的处理
//keywordQuery.should(QueryBuilders.queryStringQuery(words).field("teacher", 8f));
keywordQuery.minimumShouldMatch(1);
boolQuery.must(keywordQuery);
//boolQuery.must(QueryBuilders.wildcardQuery("name", "*"+params.getKeywords()+"*").boost(9f));
//teacher
//
// BoolQueryBuilder keywordQuery = QueryBuilders.boolQuery();
//
//// //相当于 like查询 它的权重最高 8位权重
//// boolQuery.should(QueryBuilders.queryStringQuery(params.getKeywords()).field("name", 8f));
//// //其它是教师,教师也是 like查询 它只是2位权重
//// boolQuery.should(QueryBuilders.queryStringQuery(params.getKeywords()).field("teacher", 5f));
//// //关键词查询
//// boolQuery.should(QueryBuilders.queryStringQuery(params.getKeywords()).field("keywords", 3f));
////
//// //boolQuery.should(QueryBuilders.fuzzyQuery("keywords",params.getKeywords()).boost(3f));
//// //分词查询权重是1默念
//// boolQuery.should(QueryBuilders.multiMatchQuery(params.getKeywords(),"summary"));
//
// //相当于 like查询 它的权重最高 8位权重
// keywordQuery.should(QueryBuilders.queryStringQuery(params.getKeywords()).field("name", 8f));
// //其它是教师,教师也是 like查询 它只是5权重
// //keywordQuery.should(QueryBuilders.queryStringQuery(params.getKeywords()).field("teacher", 5f));
// //关键词查询 like查询 它只是3权重
// //keywordQuery.should(QueryBuilders.queryStringQuery(params.getKeywords()).field("keywords", 3f));
//
// //boolQuery.should(QueryBuilders.fuzzyQuery("keywords",params.getKeywords()).boost(3f));
// //分词查询权重是1
// //keywordQuery.should(QueryBuilders.multiMatchQuery(params.getKeywords(),"summary"));
//
// //最少也能匹配到一个
// keywordQuery.minimumShouldMatch(1);
// boolQuery.must(keywordQuery);
}
//课程时长查询
// if(params.getDuration()!=null || params.getMaxDuration()!=null) {
// RangeQueryBuilder durationQuery = QueryBuilders.rangeQuery("duration");
// if(params.getDuration()!=null) {
// durationQuery.gte(params.getDuration());
// }
// if(params.getMaxDuration()!=null) {
// durationQuery.lte(params.getMaxDuration());
// }
// boolQuery.filter(durationQuery);
// }
//加入条件, 排序最热,无关键词查询时才进行搜索
if(StringUtils.isBlank(params.getKeywords()) && params.getOrderType()!=null && params.getOrderType()==2) {
RangeQueryBuilder timeLimit = QueryBuilders.rangeQuery("publishTime");
Long second = LocalDateTime.of(2022,1, 1, 0, 0).toEpochSecond(ZoneOffset.of("+8"));
timeLimit.gte(second);
boolQuery.filter(timeLimit);
}
//System.out.println(boolQuery.toString());
return boolQuery;
}
@Override
public List<CourseFullText> search(String indexNames, int num, CourseFullText paras) throws Exception{
SearchRequest searchRequest = new SearchRequest();
if(StringUtils.isNotBlank(indexNames)) {
String[] names=indexNames.split(",");
searchRequest.indices(names);
}
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
if(num==0) {
num=10;
}
sourceBuilder.size(num);
BoolQueryBuilder boolQuery=createQuery(paras);
sourceBuilder.query(boolQuery);
//排序
if(StringUtils.isBlank(paras.getKeywords())) {
sourceBuilder.sort("isTop",SortOrder.DESC);
sourceBuilder.sort("topTime",SortOrder.DESC);
}
if(paras.getOrderType()!=null) {
if(paras.getOrderType()==1) {
sourceBuilder.sort("publishTime",SortOrder.DESC);
}else if(paras.getOrderType()==2) {
sourceBuilder.sort("studies",SortOrder.DESC);
sourceBuilder.sort("publishTime",SortOrder.DESC);
}
}
//sourceBuilder.sort("isTop",SortOrder.DESC);
//sourceBuilder.sort("publishTime",SortOrder.DESC);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//name
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.requireFieldMatch(true);//是否多个字段都高亮
highlightBuilder.preTags("<span style='color:#3e7fff'>");//前缀后缀
highlightBuilder.postTags("</span>");
HighlightBuilder.Field nameHighlight=new HighlightBuilder.Field("name");
HighlightBuilder.Field summaryHighlight=new HighlightBuilder.Field("summary");
HighlightBuilder.Field teacherHighlight=new HighlightBuilder.Field("teacher");
HighlightBuilder.Field keywordsHighlight=new HighlightBuilder.Field("keywords");
highlightBuilder.field(nameHighlight);
highlightBuilder.field(teacherHighlight);
highlightBuilder.field(keywordsHighlight);
highlightBuilder.field(summaryHighlight);
sourceBuilder.highlighter(highlightBuilder);
searchRequest.source(sourceBuilder);
List<CourseFullText> list=new ArrayList<>();
ObjectMapper mapper=new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
log.info("共查询到 "+hits.getTotalHits());
for (SearchHit hit : hits) {
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
HighlightField name = highlightFields.get("name");
HighlightField summary = highlightFields.get("summary");
HighlightField teacher = highlightFields.get("teacher");
HighlightField keywords = highlightFields.get("keywords");
//Map<String, Object> sourceAsMap = hit.getSourceAsMap();//原来的结果
String sourceAsString = hit.getSourceAsString();
//log.info(sourceAsString);
try {
CourseFullText cft =mapper.readValue(sourceAsString, CourseFullText.class);
cft.setEsId(hit.getId());
//以下不再加高亮显,高亮显在页面中去实现
// if(name!= null){
// Text[] fragments = name.fragments();
// StringBuffer fmtStr = new StringBuffer("");
// for (Text fragment : fragments) {
// fmtStr.append(fragment);
// }
// cft.setName(fmtStr.toString());
// }
//
// if(summary!= null){
// Text[] fragments = summary.fragments();
// StringBuffer fmtStr = new StringBuffer("");
// for (Text fragment : fragments) {
// fmtStr.append(fragment);
// }
// cft.setSummary(fmtStr.toString());
// }
//去掉老师的高亮显
// if(teacher!= null){
// Text[] fragments = teacher.fragments();
// StringBuffer fmtStr = new StringBuffer("");
// for (Text fragment : fragments) {
// fmtStr.append(fragment);
// }
// cft.setTeacher(fmtStr.toString());
// }
// if(keywords!= null){
// Text[] fragments = keywords.fragments();
// StringBuffer fmtStr = new StringBuffer("");
// for (Text fragment : fragments) {
// fmtStr.append(fragment);
// }
// cft.setKeywords(fmtStr.toString());
// }
list.add(cft);
}catch(Exception ee) {
log.error("转化查询结果错误",ee);
//ee.printStackTrace();
}
}
return list;
}
@Override
public PageList<CourseFullText> search(String indexNames, int startRow, int pageSize, CourseFullText paras) throws Exception{
SearchRequest searchRequest = new SearchRequest();
if(StringUtils.isNotBlank(indexNames)) {
String[] names=indexNames.split(",");
searchRequest.indices(names);
}
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.from(startRow);
sourceBuilder.size(pageSize);
BoolQueryBuilder boolQuery=createQuery(paras);
if(boolQuery.hasClauses()) {
sourceBuilder.query(boolQuery);
}
//排序
if(StringUtils.isBlank(paras.getKeywords())) {
sourceBuilder.sort("isTop",SortOrder.DESC);
//sourceBuilder.sort("topTime",SortOrder.DESC);
}
if(paras.getOrderType()!=null) {
if(paras.getOrderType()==1) {
sourceBuilder.sort("publishTime",SortOrder.DESC);
}else if(paras.getOrderType()==2) {
sourceBuilder.sort("studies",SortOrder.DESC);
}
}
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//name
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.requireFieldMatch(true);//是否多个字段都高亮
highlightBuilder.preTags("<span style='color:red'>");//前缀后缀
highlightBuilder.postTags("</span>");
HighlightBuilder.Field nameHighlight=new HighlightBuilder.Field("name");
HighlightBuilder.Field summaryHighlight=new HighlightBuilder.Field("summary");
HighlightBuilder.Field teacherHighlight=new HighlightBuilder.Field("teacher");
HighlightBuilder.Field keywordsHighlight=new HighlightBuilder.Field("keywords");
highlightBuilder.field(nameHighlight);
highlightBuilder.field(teacherHighlight);
highlightBuilder.field(keywordsHighlight);
highlightBuilder.field(summaryHighlight);
sourceBuilder.highlighter(highlightBuilder);
searchRequest.source(sourceBuilder);
List<CourseFullText> list=new ArrayList<>();
ObjectMapper mapper=new ObjectMapper();
SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
//log.info("共查询到 "+hits.getTotalHits());
for (SearchHit hit : hits) {
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
HighlightField name = highlightFields.get("name");
HighlightField summary = highlightFields.get("summary");
HighlightField teacher = highlightFields.get("teacher");
HighlightField keywords = highlightFields.get("keywords");
String sourceAsString = hit.getSourceAsString();
try {
CourseFullText cft =mapper.readValue(sourceAsString, CourseFullText.class);
cft.setEsId(hit.getId());
// if(name!= null){
// Text[] fragments = name.fragments();
// StringBuffer fmtStr = new StringBuffer("");
// for (Text fragment : fragments) {
// fmtStr.append(fragment);
// }
// cft.setName(fmtStr.toString());
// }
if(summary!= null){
Text[] fragments = summary.fragments();
StringBuffer fmtStr = new StringBuffer("");
for (Text fragment : fragments) {
fmtStr.append(fragment);
}
cft.setSummary(fmtStr.toString());
}
if(teacher!= null){
Text[] fragments = teacher.fragments();
StringBuffer fmtStr = new StringBuffer("");
for (Text fragment : fragments) {
fmtStr.append(fragment);
}
cft.setTeacher(fmtStr.toString());
}
if(keywords!= null){
Text[] fragments = keywords.fragments();
StringBuffer fmtStr = new StringBuffer("");
for (Text fragment : fragments) {
fmtStr.append(fragment);
}
cft.setKeywords(fmtStr.toString());
}
list.add(cft);
}catch(Exception ee) {
log.error("转化json到对应失败");
}
}
PageList<CourseFullText> rs=new PageList<CourseFullText>();
rs.setCount((int)hits.getTotalHits().value);
rs.setPageSize(pageSize);
rs.setList(list);
return rs;
}
@Override
public void removeByDocId(String indexName, String id) {
DeleteRequest deleteRequest = new DeleteRequest(indexName);
deleteRequest.id(id);
try {
DeleteResponse deleteResponse = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
if (deleteResponse.getResult() == DocWriteResponse.Result.NOT_FOUND) {
log.error("删除失败,未找到索引id是【"+id+"】的文档");
}
//restHighLevelClient.close();
} catch (IOException e) {
log.error("删除异常:"+e.getMessage());
}
}
@Override
public boolean deleteById(String indexName, String id) throws IOException {
DeleteByQueryRequest deleteRequest=new DeleteByQueryRequest(indexName);
deleteRequest.setQuery(new TermQueryBuilder("id",id));
BulkByScrollResponse response = restHighLevelClient.deleteByQuery(deleteRequest, RequestOptions.DEFAULT);
long n=response.getStatus().getTotal();
if(n==0) {
log.error("按id删除失败",response);
return true;
}else {
return false;
}
//restHighLevelClient.close();
}
}

View File

@@ -0,0 +1,289 @@
package com.xboe.module.elasticsearc;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xboe.common.PageList;
import com.xboe.module.course.dto.CourseStudyDto;
import com.xboe.module.course.service.ICourseStudySearch;
import lombok.extern.slf4j.Slf4j;
/**
* 课程学习的ES实现
* @author seastar
*
*/
@Slf4j
@Service
public class CourseStudyElasticsearchImpl implements ICourseStudySearch{
@Resource
RestHighLevelClient restHighLevelClient;
@Resource
ElasticsearchUtil esUtil;
@Override
public void createIndex() throws Exception{
boolean isExists = esUtil.isIndexExists(IndexName);
if(isExists) {
throw new Exception("索引已存在");
}
XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject();
builder.field("properties").startObject();
builder.field("id").startObject().field("index", "true").field("type", "keyword").endObject();
builder.field("accountId").startObject().field("type", "keyword").endObject();
builder.field("courseId").startObject().field("type", "keyword").endObject();
builder.field("courseName").startObject().field("type", "keyword").endObject();
builder.field("courseImage").startObject().field("type", "keyword").endObject();
builder.field("courseType").startObject().field("type", "integer").endObject();
builder.field("source").startObject().field("type", "integer").endObject();
builder.field("startTime").startObject().field("type", "integer").endObject();
builder.field("status").startObject().field("type", "integer").endObject();
builder.field("progress").startObject().field("type", "integer").endObject();
builder.field("applyStatus").startObject().field("type", "integer").endObject();
builder.field("attendCourseTime").startObject().field("type", "integer").endObject();
builder.field("courseAddress").startObject().field("type", "keyword").endObject();
builder.endObject();
builder.endObject();
CreateIndexRequest createIndexRequest = new CreateIndexRequest(IndexName);
createIndexRequest.mapping(builder);
CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
boolean acknowledged = createIndexResponse.isAcknowledged();
if (!acknowledged) {
log.error("创建课程学习索引失败",createIndexResponse);
throw new Exception("创建索引失败");
}
}
@Override
public void deleteIndex() {
esUtil.deleteIndex(IndexName);
}
@Override
public String publishOrUpdate(CourseStudyDto dto,String docId) throws IOException {
boolean exists=false;
if(StringUtils.isNotBlank(docId)) {
GetRequest getRequest=new GetRequest(IndexName,docId);
exists = restHighLevelClient.exists(getRequest, RequestOptions.DEFAULT);
}
//System.out.println(item.getName()+"="+item.getType());
if(exists) {
UpdateRequest updateRequest = new UpdateRequest(IndexName, docId);
ObjectMapper mapper=new ObjectMapper();
String textJson =mapper.writeValueAsString(dto);
updateRequest.doc(textJson, XContentType.JSON);
UpdateResponse updateResponse = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
int ok=updateResponse.status().getStatus();
if (ok!=200) {
log.error("更新【"+docId+"】失败",updateResponse);
}
}else {
IndexRequest indexRequest = new IndexRequest(IndexName);
ObjectMapper mapper=new ObjectMapper();
String textJson =mapper.writeValueAsString(dto);
indexRequest.source(textJson, XContentType.JSON);
IndexResponse indexResponse = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
if (indexResponse != null) {
String id = indexResponse.getId();
String index = indexResponse.getIndex();
long version = indexResponse.getVersion();
if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
log.info("新增全文索引文档成功! " + index + "-" + id + "-" + version);
return id;
} else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
log.info("修改文档成功!");
return id;
}
}
}
return docId;
}
@Override
public void updateFieldByDocId(String field, Object value, String docId) throws Exception {
UpdateRequest updateRequest = new UpdateRequest(IndexName, docId);
ObjectMapper mapper=new ObjectMapper();
Map<String,Object> map=new HashMap<String,Object>();
map.put(field, value);
String textJson =mapper.writeValueAsString(map);
updateRequest.doc(textJson, XContentType.JSON);
UpdateResponse updateResponse = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
if (updateResponse.getResult() == DocWriteResponse.Result.UPDATED) {
log.info("更新课程学习字段【"+docId+"】【"+field+"】成功!");
} else {
log.error("更新课程学习字段【"+docId+"】【"+field+"】失败");
}
}
@Override
public void removeByDocId(String id) throws Exception {
DeleteRequest deleteRequest = new DeleteRequest(IndexName);
deleteRequest.id(id);
try {
DeleteResponse deleteResponse = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
if (deleteResponse.getResult() == DocWriteResponse.Result.NOT_FOUND) {
log.error("删除失败,未找到索引id是【"+id+"】的文档");
}
//restHighLevelClient.close();
} catch (IOException e) {
log.error("删除ES索引错误",e);
}
}
@Override
public PageList<CourseStudyDto> search(int startRow, int pageSize, CourseStudyDto dto) throws Exception {
BoolQueryBuilder boolQuery= QueryBuilders.boolQuery();
if(StringUtils.isNotBlank(dto.getCourseName())) {
String words=QueryParser.escape(dto.getCourseName());
boolQuery.filter(QueryBuilders.wildcardQuery("courseName.keyword", "*"+words+"*"));
}
if(dto.getCourseType()!=null) {
if(dto.getCourseType()==10 || dto.getCourseType()==20) {
int[] types=new int[] {10,20};
boolQuery.filter(QueryBuilders.termsQuery("courseType",types));
}else {
boolQuery.filter(QueryBuilders.termQuery("courseType",dto.getCourseType()));
}
}
if(dto.getStatus()!=null) {
boolQuery.filter(QueryBuilders.termQuery("status",dto.getStatus()));
}
if(dto.getSource()!=null) {
boolQuery.filter(QueryBuilders.termQuery("source",dto.getSource()));
}
if(dto.getAccountId()!=null) {
boolQuery.filter(QueryBuilders.termQuery("accountId",dto.getAccountId()));
}
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices(IndexName);
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.from(startRow);
sourceBuilder.size(pageSize);
if(boolQuery.hasClauses()) {
sourceBuilder.query(boolQuery);
}
sourceBuilder.sort("startTime",SortOrder.DESC);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
searchRequest.source(sourceBuilder);
//进行查询
List<CourseStudyDto> list=new ArrayList<>();
ObjectMapper mapper=new ObjectMapper();
SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
//log.info("共查询到 "+hits.getTotalHits());
for (SearchHit hit : hits) {
String sourceAsString = hit.getSourceAsString();
try {
CourseStudyDto cft =mapper.readValue(sourceAsString, CourseStudyDto.class);
cft.setEsId(hit.getId());
list.add(cft);
}catch(Exception e) {
log.error("转化json到对应失败",sourceAsString);
}
}
PageList<CourseStudyDto> rs=new PageList<CourseStudyDto>();
rs.setCount((int)hits.getTotalHits().value);
rs.setPageSize(pageSize);
rs.setList(list);
return rs;
}
@Override
public void updateStatusAndProcessByDocId(String docId, int status, int progress) throws Exception {
//更新状态和进度
UpdateRequest updateRequest = new UpdateRequest(IndexName, docId);
ObjectMapper mapper=new ObjectMapper();
Map<String,Object> map=new HashMap<String,Object>();
map.put("status",status);
map.put("progress",progress);
String textJson =mapper.writeValueAsString(map);
updateRequest.doc(textJson, XContentType.JSON);
UpdateResponse updateResponse = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
if (updateResponse.getResult() == DocWriteResponse.Result.UPDATED) {
log.info("更新课程学习状态进度成功!");
} else {
log.error("更新课程学习状态进度失败");
}
}
@Override
public void removeByStudyId(String id) {
//根据学习id删除
try {
DeleteByQueryRequest deleteRequest=new DeleteByQueryRequest(IndexName);
deleteRequest.setQuery(new TermQueryBuilder("id",id));
BulkByScrollResponse response = restHighLevelClient.deleteByQuery(deleteRequest, RequestOptions.DEFAULT);
long n=response.getStatus().getTotal();
if(n==0) {
log.error("按id删除失败",response);
}
}catch(Exception e){
log.error("按id【"+id+"】删除失败",e);
}
}
}

View File

@@ -0,0 +1,64 @@
package com.xboe.module.elasticsearc;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.xboe.common.utils.StringUtil;
@Configuration
public class ElasticsearchConfig {
@Value("${xboe.elasticsearch.server.ip}")
private String esIp="127.0.0.1";
@Value("${xboe.elasticsearch.server.port}")
private int esPort=9200;
@Value("${xboe.elasticsearch.server.user}")
private String esUser;
@Value("${xboe.elasticsearch.server.password}")
private String esUserword;
@Bean
public RestClientBuilder restClientBuilder() {
HttpHost[] hosts=new HttpHost[]{new HttpHost(this.esIp,this.esPort,"http")};
if(StringUtil.isBlank(esUser)) {
RestClientBuilder builder = RestClient.builder(hosts);
return builder;
}else {
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,new UsernamePasswordCredentials(esUser,esUserword)); //es账号密码默认用户名为elastic
RestClientBuilder builder = RestClient.builder(hosts).setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
httpClientBuilder.disableAuthCaching();
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
});
return builder;
}
}
@Bean(name = "highLevelClient")
public RestHighLevelClient highLevelClient(@Autowired RestClientBuilder restClientBuilder) {
// restClientBuilder.setMaxRetryTimeoutMillis(60000);
return new RestHighLevelClient(restClientBuilder);
}
}

View File

@@ -0,0 +1,57 @@
package com.xboe.module.elasticsearc;
import java.io.IOException;
import javax.annotation.Resource;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.springframework.stereotype.Component;
@Component
public class ElasticsearchUtil {
@Resource
RestHighLevelClient restHighLevelClient;
/**
* 判断索引是否存在
*
* @param indexName
* @return
*/
public boolean isIndexExists(String indexName) {
boolean exists = false;
try {
GetIndexRequest getIndexRequest = new GetIndexRequest(indexName);
getIndexRequest.humanReadable(true);
exists = restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
return exists;
}
/**
* 删除索引
*
* @param indexName
* @return
*/
public boolean deleteIndex(String indexName) {
boolean acknowledged = false;
try {
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(indexName);
deleteIndexRequest.indicesOptions(IndicesOptions.LENIENT_EXPAND_OPEN);
AcknowledgedResponse delete = restHighLevelClient.indices().delete(deleteIndexRequest,RequestOptions.DEFAULT);
acknowledged = delete.isAcknowledged();
} catch (IOException e) {
e.printStackTrace();
}
return acknowledged;
}
}

View File

@@ -0,0 +1,246 @@
package com.xboe.module.elasticsearc.api;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.client.GetAliasesResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.cluster.metadata.AliasMetadata;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.xboe.core.JsonResponse;
import com.xboe.core.JsonResponseStatus;
import com.xboe.core.api.ApiBaseController;
import com.xboe.module.elasticsearc.ElasticsearchUtil;
import lombok.extern.slf4j.Slf4j;
/**
* 课程内容全文检索的实现
*
*/
@Slf4j
@RestController
@RequestMapping(value="/api/fulltext/es")
public class ElasticsearchAdminApi extends ApiBaseController{
@Resource
private RestHighLevelClient restHighLevelClient;
@Resource
ElasticsearchUtil esUtil;
/**
* 创建新的索引
* @param indexName
* @return
*/
@RequestMapping(value = "/index/create", method = RequestMethod.POST)
public JsonResponse<Boolean> createIndex(String name) {
try {
XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject();
builder.field("properties").startObject();
builder.field("id").startObject().field("index", "true").field("type", "keyword").endObject();
builder.field("title").startObject().field("type", "text").field("analyzer", "ik_max_word").field("search_analyzer","ik_smart").endObject();
builder.field("keyword").startObject().field("type", "keyword").endObject();
builder.field("url").startObject().field("type", "text").endObject();
builder.field("subtitle").startObject().field("type", "text").field("analyzer", "ik_max_word").field("search_analyzer","ik_smart").endObject();
builder.field("content").startObject().field("type", "text").field("analyzer", "ik_max_word").field("search_analyzer","ik_smart").endObject();
builder.field("time").startObject().field("type", "text").endObject();
builder.field("image").startObject().field("type", "text").endObject();
builder.endObject();
builder.endObject();
CreateIndexRequest createIndexRequest = new CreateIndexRequest(name);
createIndexRequest.mapping(builder);
CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
boolean acknowledged = createIndexResponse.isAcknowledged();
if (acknowledged) {
return wrap(true);
} else {
return error("创建失败");
}
} catch (IOException e) {
e.printStackTrace();
log.error("创建失败",e.getMessage());
return error("创建失败",e.getMessage(),false);
}
}
/**是否存在索引接口"**/
@RequestMapping(value = "/index/exists", method = {RequestMethod.GET,RequestMethod.POST})
public JsonResponse<Boolean> indexExists(String name) {
boolean isExists = esUtil.isIndexExists(name);
return wrap(isExists);
}
/**得到全部索引*/
@RequestMapping(value = "/index/all", method = RequestMethod.GET)
public JsonResponse<Set<String>> indexAll() {
try {
GetAliasesRequest aliasesRequest = new GetAliasesRequest();
//restHighLevelClient.indices().get(getIndexRequest, options)
GetAliasesResponse getAliasesResponse = restHighLevelClient.indices().getAlias(aliasesRequest,RequestOptions.DEFAULT);
Map<String, Set<AliasMetadata>> map = getAliasesResponse.getAliases();
Set<String> indices = map.keySet();
List<String> indexNames=new ArrayList<>();
for(String key : indices) {
if(!key.startsWith(".")) {
indexNames.add(key);
//提取索引信息
//GetIndexRequest indexRequest = new GetIndexRequest(key);
//GetIndexResponse indexResponse = restHighLevelClient.indices().get(indexRequest, RequestOptions.DEFAULT);
//String numberOfShardsString = indexResponse.getSetting("index", "index.number_of_shards");
//Settings indexSettings = indexResponse.getSettings().get("index");
//Integer numberOfShards = indexSettings.getAsInt("index.number_of_shards", null);
//System.out.println("numberOfShardsString="+numberOfShardsString);
//System.out.println("numberOfShards="+numberOfShards);
// Set<AliasMetadata> sets=map.get(key);
// System.out.println("======="+key+"=============");
// for(AliasMetadata am : sets) {
// System.out.println(am.getAlias()+","+am.getIndexRouting()+","+am.getSearchRouting());
// }
}
}
// if(indexNames.size()>0) {
//
// String[] names=new String[indexNames.size()];
// indexNames.toArray(names);
// ClusterHealthRequest healthRequest = new ClusterHealthRequest(names);
//
// ClusterHealthResponse healths=restHighLevelClient.cluster().health(healthRequest, RequestOptions.DEFAULT);
//
// for(ClusterIndexHealth health:healths.getIndices().values()) {
// String index = health.getIndex();
// int numberOfShards = health.getNumberOfShards();
// int numberOfReplicas = health.getNumberOfReplicas();
// System.out.println("index = "+index);//索引名
// System.out.println("numberOfShards = "+numberOfShards);//分片数量
// System.out.println("numberOfReplicas = "+numberOfReplicas);//副本数量
//
// ClusterHealthStatus clusterHealthStatus = health.getStatus();
// System.out.println("clusterHealthStatus = "+clusterHealthStatus.toString());//健康状态
// }
// }
return wrap(indices);
} catch (IOException e) {
e.printStackTrace();
return error("查询索引失败",e.getMessage());
}
}
/**
* 删除索引
* @param indexName
* @return
*/
//@ApiOperation(value = "es测试删除索引接口", notes = "es测试删除索引接口")
@RequestMapping(value = "/index/delete", method = RequestMethod.POST)
public JsonResponse<Boolean> deleteIndex(String name) {
if(StringUtils.isBlank(name)) {
return badRequest("未指定索引");
}
boolean isDelete = esUtil.deleteIndex(name);
if (isDelete) {
return wrap(true);
} else {
return wrap(false);
}
}
/**
* es测试删除接口
* @param id
* @param indexName
* @return
*/
@RequestMapping(value = "/data/delete", method = {RequestMethod.GET,RequestMethod.POST})
public JsonResponse<Boolean> testESDelete(String id, String indexName) {
DeleteRequest deleteRequest = new DeleteRequest(indexName);
deleteRequest.id(id);
try {
DeleteResponse deleteResponse = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
if (deleteResponse.getResult() == DocWriteResponse.Result.NOT_FOUND) {
return wrap(JsonResponseStatus.NOT_FOUND,"删除失败",false);
} else {
return wrap(true);
}
} catch (IOException e) {
e.printStackTrace();
return error("删除异常",e.getMessage(),false);
}
}
/**
* 批量删除
* @param id
* @param indexName
* @return
*/
@RequestMapping(value = "/data/batch-delete", method = {RequestMethod.POST})
public JsonResponse<Long> testESDelete(String indexName,String field,String value) {
if(StringUtils.isBlank(indexName)) {
return badRequest("未指定索引");
}
if(StringUtils.isBlank(field)) {
return badRequest("未指定类型");
}
if(value==null) {
return badRequest("未指定值");
}
DeleteByQueryRequest deleteRequest=new DeleteByQueryRequest(indexName);
System.out.println("value="+value);
if(field.equals("type")) {
deleteRequest.setQuery(new TermQueryBuilder(field,Integer.valueOf(value)));
}else if(field.equals("source")){
deleteRequest.setQuery(new TermQueryBuilder(field,(String)value));
}else {
deleteRequest.setQuery(new TermQueryBuilder(field,(String)value));
}
deleteRequest.setBatchSize(1000);
deleteRequest.setRefresh(true);
try {
BulkByScrollResponse response = restHighLevelClient.deleteByQuery(deleteRequest, RequestOptions.DEFAULT);
long n=response.getStatus().getBulkRetries();
return success(n);
} catch (IOException e) {
log.error("批量删除失败",e);
return error("批量删除失败",e.getMessage(),0l);
}
}
}

View File

@@ -0,0 +1,8 @@
package com.xboe.module.elasticsearc.api;
/**
* 全文检索查询实现
*/
public class ElasticsearchApi {
}

View File

@@ -0,0 +1,42 @@
package com.xboe.module.elasticsearc.api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.xboe.common.PageList;
import com.xboe.common.Pagination;
import com.xboe.core.JsonResponse;
import com.xboe.core.api.ApiBaseController;
import com.xboe.module.course.dto.CourseFullText;
import com.xboe.module.course.service.ICourseFullTextSearch;
import lombok.extern.slf4j.Slf4j;
/**
* 全文检索查询实现
*/
@Slf4j
@RestController
@RequestMapping(value="/api/fulltext/course")
public class ElasticsearchCourseApi extends ApiBaseController{
@Autowired
ICourseFullTextSearch courseSearch;
/**
* 初始化所有的课程内容
* @return
*/
@RequestMapping(value = "/search", method = {RequestMethod.GET,RequestMethod.POST})
public JsonResponse<PageList<CourseFullText>> search(Pagination page, CourseFullText cft) {
try {
PageList<CourseFullText> list = courseSearch.search(ICourseFullTextSearch.DEFAULT_INDEX_NAME,page.getStartRow(),page.getPageSize(), cft);
return success(list);
}catch(Exception e) {
log.error("课程全文检索查询错误",e);
return error("课程全文检索查询错误",e.getMessage());
}
}
}