package com.product.lucene.service;
|
|
import com.alibaba.fastjson.JSONObject;
|
import com.product.common.lang.StringUtils;
|
import com.product.core.config.CoreConst;
|
import com.product.core.dao.BaseDao;
|
import com.product.core.entity.FieldSetEntity;
|
import com.product.core.permission.PermissionService;
|
import com.product.lucene.config.CmnConst;
|
import com.product.lucene.util.FileUtils;
|
import com.product.util.BaseUtil;
|
|
import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
|
import org.apache.lucene.document.*;
|
import org.apache.lucene.index.IndexWriter;
|
import org.apache.lucene.index.Term;
|
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
|
import org.apache.lucene.queryparser.classic.QueryParser;
|
import org.apache.lucene.search.*;
|
import org.apache.lucene.search.highlight.Fragmenter;
|
import org.apache.lucene.search.highlight.Highlighter;
|
import org.apache.lucene.search.highlight.QueryScorer;
|
import org.apache.lucene.search.highlight.SimpleFragmenter;
|
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
|
import java.io.File;
|
import java.io.IOException;
|
import java.text.ParseException;
|
import java.util.ArrayList;
|
import java.util.List;
|
|
/**
|
* 文件检索
|
*/
|
@Service("luceneService")
|
public class LuceneService{
|
|
@Autowired
|
BaseDao baseDao;
|
|
@Autowired
|
private IndexWriter indexWriter;
|
|
@Autowired
|
PermissionService permissionService;
|
|
@Autowired
|
private SearcherManager searcherManager;
|
|
/**
|
* 创建索引
|
* @param fse
|
* @throws IOException
|
*/
|
public void createdIndex(FieldSetEntity fse) {
|
String function_uuid=fse.getString(CoreConst.FUNCTION_UUID); //获取功能
|
File file=(File)fse.getObject("file"); //获取附件
|
|
//获取全文检索配置
|
FieldSetEntity fseConfig=baseDao.getFieldSetEntityByFilter(CmnConst.PRODUCT_SYS_DOCUMENT_SEARCH, "function_uuid=?", new Object[] {function_uuid}, false);
|
if (fseConfig!=null) {
|
String table_uuid=fseConfig.getString(CmnConst.TABLE_NAME);
|
|
//获取缓存表配置
|
FieldSetEntity fseTable=baseDao.getFieldSetEntity(CoreConst.PRODUCT_SYS_DATAMODEL_TABLE, table_uuid, false);
|
if (fseTable!=null) {
|
|
//获取附件uuids
|
String attachments=fse.getString(CmnConst.ATTACHMENT_UUID);
|
if (!StringUtils.isEmpty(attachments)) {
|
|
//遍历获取附件信息
|
String [] attachment=attachments.split(",");
|
List<Document> docs=new ArrayList<>();
|
for (int i = 0; i < attachment.length; i++) {
|
|
//获取附件信息
|
FieldSetEntity fseAttachment=baseDao.getFieldSetEntity(CmnConst.PRODUCT_SYS_ATTACHMENTS, attachment[i], false);
|
if (fseAttachment!=null) {
|
|
if (file!=null) {
|
//生成索引信息
|
Document doc=new Document();
|
doc.add(new StringField(CoreConst.UUID, attachment[i], Field.Store.YES)); //附件UUID
|
doc.add(new TextField(CoreConst.FUNCTION_UUID, function_uuid, Field.Store.YES)); //功能UUID
|
doc.add(new TextField(CmnConst.FILE_NAME, fseAttachment.getString(CmnConst.FILE_NAME), Field.Store.YES)); //文件名
|
doc.add(new TextField(CmnConst.FILE_CONTENT, FileUtils.FileToString(file), Field.Store.YES)); //文件内内容
|
docs.add(doc);
|
}
|
}
|
}
|
//写入索引
|
try {
|
indexWriter.addDocuments(docs);
|
indexWriter.commit();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
}
|
file.delete();
|
}
|
|
|
/**
|
* 文档检索
|
* @param fse
|
* @return
|
* @throws Exception
|
* @throws ParseException
|
*/
|
public JSONObject searchProduct(FieldSetEntity fse) throws Exception, ParseException {
|
searcherManager.maybeRefresh();
|
IndexSearcher indexSearcher = searcherManager.acquire();
|
|
//文档信息汇总
|
List<JSONObject> jsonTotal=new ArrayList<>();
|
JSONObject jsonReturn=new JSONObject();
|
|
// 模糊匹配,匹配词
|
String search_key=fse.getString(CmnConst.SEARCH_KEY);
|
if (!BaseUtil.strIsNull(search_key)) {
|
//查询解析器
|
QueryParser parser = new MultiFieldQueryParser(new String [] {CmnConst.FILE_NAME,CmnConst.FILE_CONTENT}, new SmartChineseAnalyzer());
|
Query query = parser.parse(search_key);
|
|
//高亮格式
|
SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter(CmnConst.HIGHLIGHT_BEFORE, CmnConst.HIGHLIGHT_AFTER);
|
//高亮匹配器
|
Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));
|
Fragmenter fragmenter = new SimpleFragmenter(100);
|
highlighter.setTextFragmenter(fragmenter);
|
|
//分页查询文档
|
TopDocs topDocs = searchByPage(fse.getInteger(CoreConst.CPAGE), fse.getInteger(CoreConst.PAGESIZE), indexSearcher, query);
|
|
ScoreDoc[] hits = topDocs.scoreDocs;
|
for (int i = 0; i < hits.length; i++) {
|
Document doc = indexSearcher.doc(hits[i].doc);
|
JSONObject json=new JSONObject();
|
if (!StringUtils.isEmpty(doc.get(CoreConst.FUNCTION_UUID))) {
|
getConfig(json, doc.get(CoreConst.FUNCTION_UUID), doc.get(CoreConst.UUID));
|
}
|
json.put(CoreConst.FUNCTION_UUID, doc.get(CoreConst.FUNCTION_UUID));
|
|
// 内容增加高亮显示
|
String file_name=highlighter.getBestFragment(new SmartChineseAnalyzer(), CmnConst.FILE_NAME,doc.get(CmnConst.FILE_NAME));
|
if (StringUtils.isEmpty(file_name)) {
|
file_name=doc.get(CmnConst.FILE_NAME);
|
}
|
String file_content=highlighter.getBestFragment(new SmartChineseAnalyzer(), CmnConst.FILE_CONTENT,doc.get(CmnConst.FILE_CONTENT));
|
if (StringUtils.isEmpty(file_content)) {
|
file_content=doc.get(CmnConst.FILE_CONTENT);
|
}
|
json.put(CmnConst.FILE_NAME, file_name);
|
json.put(CmnConst.FILE_CONTENT, file_content);
|
jsonTotal.add(json);
|
}
|
|
jsonReturn.put(CmnConst.TOTALCOUNT, topDocs.totalHits.value);
|
}
|
|
jsonReturn.put(CmnConst.DATA, jsonTotal);
|
return jsonReturn;
|
}
|
|
/**
|
* 获取文档检索配置信息(权限,功能名称,跳转按钮)
|
* @param json
|
* @param function_uuid
|
* @param service_uuid
|
*/
|
public void getConfig(JSONObject json, String function_uuid, String uuid) {
|
|
FieldSetEntity fseConfig=baseDao.getFieldSetEntityByFilter(CmnConst.PRODUCT_SYS_DOCUMENT_SEARCH, "function_uuid=?", new Object[] {function_uuid}, false);
|
if (fseConfig!=null) {
|
|
FieldSetEntity fseFunction=baseDao.getFieldSetEntity(CoreConst.PRODUCT_SYS_FUNCTIONS, function_uuid, false);
|
|
//获取权限过滤字段
|
String org_fields=fseConfig.getString(CmnConst.ORG_FIELDS);
|
String user_fields=fseConfig.getString(CmnConst.USER_FIELDS);
|
|
//获取附件信息
|
FieldSetEntity fseAttachment=baseDao.getFieldSetEntity(CmnConst.PRODUCT_SYS_ATTACHMENTS, uuid, false);
|
baseDao.loadPromptData(fseAttachment);
|
if (fseAttachment!=null) {
|
StringBuilder filter=new StringBuilder();
|
filter.append(fseAttachment.getString(CmnConst.ATTACHMENT_DATA_FIELD));
|
filter.append(" =? ");
|
if (StringUtils.isEmpty(org_fields)) {
|
if (!StringUtils.isEmpty(user_fields)) {
|
filter.append(" AND ");
|
filter.append(permissionService.getDataFilter(fseAttachment.getString(CmnConst.ATTACHMENT_DATA_TABLE), user_fields));
|
}
|
}else {
|
if (StringUtils.isEmpty(user_fields)) {
|
filter.append(" AND ");
|
filter.append(permissionService.getDataFilter(org_fields));
|
}else {
|
filter.append(" AND ");
|
filter.append(permissionService.getDataFilter(fseAttachment.getString(CmnConst.ATTACHMENT_DATA_TABLE), user_fields, org_fields));
|
}
|
}
|
|
|
//获取原数据
|
FieldSetEntity fseService=baseDao.getFieldSetEntityByFilter(fseAttachment.getString(CmnConst.ATTACHMENT_DATA_TABLE), filter.toString(), new Object[] {uuid}, false);
|
if (fseService==null) {//权限过滤无原数据
|
FieldSetEntity fseService2=baseDao.getFieldSetEntityByFilter(fseAttachment.getString(CmnConst.ATTACHMENT_DATA_TABLE), fseAttachment.getString(CmnConst.ATTACHMENT_DATA_FIELD)+"=?", new Object[] {uuid}, false);
|
if (fseService2==null) {
|
// json.put("date_time", fseService2.getString(fseConfig.getString("time_field")));
|
json.put(CmnConst.TITLE, "无相关业务数据");
|
json.put(CoreConst.FUNCTION_NAME, fseFunction.getString(CoreConst.FUNCTION_NAME));
|
json.put(CmnConst.IS_PERSSION, 1);
|
}else {
|
json.put(CmnConst.SERVICE_UUID, fseService2.getString(CoreConst.UUID));
|
json.put(CmnConst.DATE_TIME, fseService2.getString(fseConfig.getString(CmnConst.TIME_FIELD)));
|
json.put(CmnConst.TITLE, fseService2.getString(fseConfig.getString(CmnConst.TITLE_FIELD)));
|
json.put(CoreConst.FUNCTION_NAME, fseFunction.getString(CoreConst.FUNCTION_NAME));
|
json.put(CmnConst.IS_PERSSION, 0);
|
}
|
|
}else {
|
json.put(CmnConst.SERVICE_UUID, fseService.getString(CoreConst.UUID));
|
json.put(CmnConst.DATE_TIME, fseService.getString(fseConfig.getString(CmnConst.TIME_FIELD)));
|
json.put(CmnConst.TITLE, fseService.getString(fseConfig.getString(CmnConst.TITLE_FIELD)));
|
json.put(CoreConst.FUNCTION_NAME, fseFunction.getString(CoreConst.FUNCTION_NAME));
|
}
|
json.put(CoreConst.CREATED_BY, fseAttachment.getString(CoreConst.CREATED_BY));
|
}
|
}
|
}
|
|
|
/**
|
* 文件检索查询分页
|
* @param cpage 当前页
|
* @param pagesize 每页大小
|
* @param searcher 查询器
|
* @param query 查询对象
|
* @return
|
* @throws IOException
|
*/
|
private TopDocs searchByPage(int cpage,int pagesize, IndexSearcher searcher, Query query) throws IOException {
|
TopDocs result = null;
|
if(query == null){
|
System.out.println(" Query is null return null ");
|
return null;
|
}
|
ScoreDoc before = null;
|
if(cpage != 1){
|
TopDocs docsBefore = searcher.search(query, (cpage-1)*pagesize);
|
ScoreDoc[] scoreDocs = docsBefore.scoreDocs;
|
if(scoreDocs.length > 0){
|
before = scoreDocs[scoreDocs.length - 1];
|
}
|
}
|
result = searcher.searchAfter(before, query, pagesize);
|
return result;
|
}
|
|
/**
|
* 根据附件uuid删除索引
|
* @param uuid
|
* @throws IOException
|
*/
|
public void deleteIndexByUUID(String uuid) throws IOException {
|
indexWriter.deleteDocuments(new Term("uuid",uuid));
|
indexWriter.commit();
|
}
|
}
|