增加elasticsearch

This commit is contained in:
暮光:城中城
2019-07-10 21:19:06 +08:00
parent 1b706019cd
commit 02a56bc6b5
19 changed files with 761 additions and 63 deletions

View File

@@ -0,0 +1,246 @@
package com.zyplayer.doc.data.service.elasticsearch.service;
import com.zyplayer.doc.data.service.elasticsearch.support.Document;
import java.util.Date;
/**
* wiki文档搜索
*
* @author 暮光:城中城
* @since 2019-07-07
*/
@Document(indexName = "zyplayer_doc", indexType = "doc_wiki")
public class EsWikiPage {
private Long id;
/**
* 空间ID
*/
private Long spaceId;
/**
* 名字
*/
private String name;
/**
* 父ID
*/
private Long parentId;
/**
* 节点类型 0=有子节点 1=终节点
*/
private Integer nodeType;
/**
* 赞的数量
*/
private Integer zanNum;
/**
* 编辑类型 0=可编辑 1=不允许编辑
*/
private Integer editType;
/**
* 创建人ID
*/
private Long createUserId;
/**
* 创建人名字
*/
private String createUserName;
/**
* 创建时间
*/
private Date createTime;
/**
* 修改人ID
*/
private Long updateUserId;
/**
* 修改人名字
*/
private String updateUserName;
/**
* 修改时间
*/
private Date updateTime;
/**
* 0=有效 1=删除
*/
private Integer delFlag;
/**
* 阅读数
*/
private Integer viewNum;
/**
* 顺序
*/
private Integer seqNo;
/**
* 内容
*/
private String content;
/**
* 预览内容
*/
private String preview;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getSpaceId() {
return spaceId;
}
public void setSpaceId(Long spaceId) {
this.spaceId = spaceId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getParentId() {
return parentId;
}
public void setParentId(Long parentId) {
this.parentId = parentId;
}
public Integer getNodeType() {
return nodeType;
}
public void setNodeType(Integer nodeType) {
this.nodeType = nodeType;
}
public Integer getZanNum() {
return zanNum;
}
public void setZanNum(Integer zanNum) {
this.zanNum = zanNum;
}
public Integer getEditType() {
return editType;
}
public void setEditType(Integer editType) {
this.editType = editType;
}
public Long getCreateUserId() {
return createUserId;
}
public void setCreateUserId(Long createUserId) {
this.createUserId = createUserId;
}
public String getCreateUserName() {
return createUserName;
}
public void setCreateUserName(String createUserName) {
this.createUserName = createUserName;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Long getUpdateUserId() {
return updateUserId;
}
public void setUpdateUserId(Long updateUserId) {
this.updateUserId = updateUserId;
}
public String getUpdateUserName() {
return updateUserName;
}
public void setUpdateUserName(String updateUserName) {
this.updateUserName = updateUserName;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public Integer getDelFlag() {
return delFlag;
}
public void setDelFlag(Integer delFlag) {
this.delFlag = delFlag;
}
public Integer getViewNum() {
return viewNum;
}
public void setViewNum(Integer viewNum) {
this.viewNum = viewNum;
}
public Integer getSeqNo() {
return seqNo;
}
public void setSeqNo(Integer seqNo) {
this.seqNo = seqNo;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getPreview() {
return preview;
}
public void setPreview(String preview) {
this.preview = preview;
}
}

View File

@@ -0,0 +1,26 @@
package com.zyplayer.doc.data.service.elasticsearch.service;
import com.zyplayer.doc.data.service.elasticsearch.support.ElaticSearchConfig;
import com.zyplayer.doc.data.service.elasticsearch.support.EsAbstractService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.stereotype.Service;
/**
* wiki文档搜索
* @author 暮光:城中城
* @since 2019-07-07
*/
@Service
@ConditionalOnBean(ElaticSearchConfig.class)
public class EsWikiPageService extends EsAbstractService<EsWikiPage> {
@Override
public Class<EsWikiPage> getObjClass() {
return EsWikiPage.class;
}
@Override
public String getPrimaryKey(EsWikiPage tableIndex) {
return String.valueOf(tableIndex.getId());
}
}

View File

@@ -0,0 +1,22 @@
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.zyplayer.doc.data.service.elasticsearch.support;
import java.lang.annotation.*;
/**
* es文档定义
* @author 暮光:城中城
* @since 2019-07-07
*/
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface Document {
String indexName();
String indexType();
}

View File

@@ -0,0 +1,41 @@
package com.zyplayer.doc.data.service.elasticsearch.support;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* 开启es客户端
*
* @author 暮光:城中城
* @since 2019-07-07
*/
@Configuration
@ConditionalOnProperty(prefix = "zyplayer.doc.manage.elasticsearch", name = "open", havingValue = "true")
public class ElaticSearchConfig {
@Value(value = "${zyplayer.doc.manage.elasticsearch.host:''}")
private String host;
@Value("${zyplayer.doc.manage.elasticsearch.port:''}")
private String port;
@Value("${zyplayer.doc.manage.elasticsearch.cluster-name:''}")
private String clusterName;
@Bean
public TransportClient esClient() throws UnknownHostException {
Settings settings = Settings.builder()
.put("cluster.name", clusterName)
.put("client.transport.sniff", true)
.build();
TransportAddress master = new TransportAddress(InetAddress.getByName(host), Integer.valueOf(port));
return new PreBuiltTransportClient(settings).addTransportAddress(master);
}
}

View File

@@ -0,0 +1,161 @@
package com.zyplayer.doc.data.service.elasticsearch.support;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.dozer.Mapper;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* es抽象类
* @author 暮光:城中城
* @since 2019-07-07
*/
public abstract class EsAbstractService<T> {
private static final Logger logger = LoggerFactory.getLogger(EsAbstractService.class);
@Resource
private TransportClient esClient;
@Resource
private Mapper mapper;
public abstract Class<T> getObjClass();
public abstract String getPrimaryKey(T table);
private String getIndexName() {
Document annotation = this.getObjClass().getAnnotation(Document.class);
return annotation.indexName();
}
private String getIndexType() {
Document annotation = this.getObjClass().getAnnotation(Document.class);
return annotation.indexType();
}
public boolean create(T table) {
String pk = getPrimaryKey(table);
IndexResponse indexResponse = this.esClient
.prepareIndex(this.getIndexName(), this.getIndexType())
.setId(pk)
.setSource(JSONObject.toJSONString(table), XContentType.JSON)
.get();
logger.debug("ElasticSearch create index with table, pk: {}", pk);
return indexResponse.status() == RestStatus.CREATED;
}
public boolean update(T table) {
String pk = getPrimaryKey(table);
UpdateResponse updateResponse = this.esClient
.prepareUpdate(this.getIndexName(), this.getIndexType(), pk)
.setDoc(JSONObject.toJSONString(table), XContentType.JSON)
.get();
logger.info("ElasticSearch update index with table, pk: {}", pk);
return updateResponse.status() == RestStatus.OK;
}
public void delete(T table) {
String pk = getPrimaryKey(table);
DeleteResponse response = this.esClient
.prepareDelete(this.getIndexName(), this.getIndexType(), pk)
.execute()
.actionGet();
if (response.getResult() == DocWriteResponse.Result.NOT_FOUND) {
logger.warn("ElasticSearch delete index id: {} but not found!", pk);
} else {
logger.warn("ElasticSearch delete index id: {}", pk);
}
}
/**
* 多条件 模糊查询查询前100条
* @param condition 查询条件
*/
public List<T> getDataByCondition(List<EsQueryColumn> condition) {
return getDataByCondition(condition, null, 0, 100).getData();
}
/**
* 多条件 模糊查询
* @param condition 查询条件
* @param startIndex 开始行
* @param pageSize 每页数量
*/
public EsPage<T> getDataByCondition(List<EsQueryColumn> condition, String[] fields, Integer startIndex, Integer pageSize) {
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
// 组装条件
condition.forEach(val -> {
if (StringUtils.isNotBlank(val.getValue())) {
if (val.getType() == 0) {
boolQueryBuilder.must(QueryBuilders.wildcardQuery(val.getKey(), val.getValue()));
} else if (val.getType() == 1) {
boolQueryBuilder.must(QueryBuilders.termQuery(val.getKey(), val.getValue()));
}
}
});
// 设置高亮标签
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.preTags("<span style=\"color:red\">");
highlightBuilder.postTags("</span>");
highlightBuilder.field("*");
SearchRequestBuilder requestBuilder = esClient.prepareSearch(this.getIndexName()).setTypes(this.getIndexType())
.setQuery(boolQueryBuilder)
.highlighter(highlightBuilder)
.setFrom(startIndex).setSize(pageSize).setExplain(true);
// 查询指定字段
if (fields != null && fields.length > 0) {
requestBuilder.setFetchSource(fields, new String[]{});
}
SearchResponse response = requestBuilder.execute().actionGet();
return responseToList(response);
}
public EsPage<T> responseToList(SearchResponse response) {
List<T> tableList = new LinkedList<>();
for (SearchHit searchHit : response.getHits().getHits()) {
// 获取表ID和表类型
Map<String, Object> sourceMap = searchHit.getSourceAsMap();
if (sourceMap == null) {
sourceMap = new HashMap<>();
}
// 获取高亮文本
Map<String, HighlightField> highlightFieldMap = searchHit.getHighlightFields();
for (String key : highlightFieldMap.keySet()) {
HighlightField hf = highlightFieldMap.get(key);
StringBuilder fragments = new StringBuilder();
for (Text text : hf.getFragments()) {
fragments.append(text.toString());
}
sourceMap.put(key, fragments.toString());
}
T table = mapper.map(sourceMap, this.getObjClass());
tableList.add(table);
}
EsPage<T> esPage = new EsPage<>();
esPage.setTotal(response.getHits().getTotalHits());
esPage.setData(tableList);
return esPage;
}
}

View File

@@ -0,0 +1,29 @@
package com.zyplayer.doc.data.service.elasticsearch.support;
import java.util.List;
/**
* es分页结果
* @author 暮光:城中城
* @since 2019-07-07
*/
public class EsPage<T> {
private Long total;
private List<T> data;
public Long getTotal() {
return total;
}
public void setTotal(Long total) {
this.total = total;
}
public List<T> getData() {
return data;
}
public void setData(List<T> data) {
this.data = data;
}
}

View File

@@ -0,0 +1,55 @@
package com.zyplayer.doc.data.service.elasticsearch.support;
/**
* es查询字段封装
* @author 暮光:城中城
* @since 2019-07-07
*/
public class EsQueryColumn {
private String key;
private String value;
// 类型0=分词搜索 1=不分词
private int type;
public EsQueryColumn(String key, String value) {
this(key, value, 0);
}
public EsQueryColumn(String key, String value, int type) {
this.key = key;
this.value = value;
this.type = type;
}
public static EsQueryColumn like(String key, String value){
return new EsQueryColumn(key, value, 0);
}
public static EsQueryColumn must(String key, String value){
return new EsQueryColumn(key, value, 1);
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
}

View File

@@ -1,20 +0,0 @@
package com.zyplayer.doc.data.web.generator;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
* 前端控制器
* </p>
*
* @author 暮光:城中城
* @since 2019-07-04
*/
@RestController
@RequestMapping("/db-datasource")
public class GeneratorDbDatasourceController {
}