package com.product.lucene.service; import com.alibaba.fastjson.JSONObject; import com.product.common.lang.StringUtils; import com.product.core.dao.BaseDao; import com.product.core.entity.FieldSetEntity; import com.product.core.permission.PermissionService; import com.product.core.websocket.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("function_uuid"); //获取功能 File file=(File)fse.getObject("file"); //获取附件 //获取全文检索配置 FieldSetEntity fseConfig=baseDao.getFieldSetEntityByFilter("product_sys_document_search", "function_uuid=?", new Object[] {function_uuid}, false); if (fseConfig!=null) { String table_uuid=fseConfig.getString("table_name"); //获取缓存表配置 FieldSetEntity fseTable=baseDao.getFieldSetEntity("product_sys_datamodel_table", table_uuid, false); if (fseTable!=null) { //获取附件uuids String attachments=fse.getString("attachment_uuid"); if (!StringUtils.isEmpty(attachments)) { //遍历获取附件信息 String [] attachment=attachments.split(","); List docs=new ArrayList<>(); for (int i = 0; i < attachment.length; i++) { //获取附件信息 FieldSetEntity fseAttachment=baseDao.getFieldSetEntity("product_sys_attachments", attachment[i], false); if (fseAttachment!=null) { if (file!=null) { //生成索引信息 Document doc=new Document(); doc.add(new StringField("uuid", attachment[i], Field.Store.YES)); //附件UUID doc.add(new TextField("function_uuid", function_uuid, Field.Store.YES)); //功能UUID doc.add(new TextField("file_name", fseAttachment.getString("file_name"), Field.Store.YES)); //文件名 doc.add(new TextField("file_content", FileUtils.FileToString(file), Field.Store.YES)); //文件内内容 docs.add(doc); } } } //写入索引 try { indexWriter.addDocuments(docs); indexWriter.commit(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } file.delete(); } /* public void createdIndex(FieldSetEntity fse) throws IOException { String function_uuid=fse.getString("function_uuid"); String service_uuid=fse.getString("service_uuid"); //获取全文检索配置 FieldSetEntity fseConfig=baseDao.getFieldSetEntityByFilter("product_sys_document_search", "function_uuid=?", new Object[] {function_uuid}, false); if (fseConfig!=null) { String table_uuid=fseConfig.getString("table_name"); String attachment_field=fseConfig.getString("attachment_file"); //获取缓存表配置 FieldSetEntity fseTable=baseDao.getFieldSetEntity("product_sys_datamodel_table", table_uuid, false); if (fseTable!=null) { //获取原数据 FieldSetEntity fseService=baseDao.getFieldSetEntityBySQL("SELECT * FROM "+fseTable.getString("table_name")+" WHERE uuid=?", new Object[] {service_uuid}, false); if (fseService!=null) { //获取附件uuids String attachments=fseService.getString(attachment_field); if (!StringUtils.isEmpty(attachments)) { //遍历获取附件信息 String [] attachment=attachments.split(","); List docs=new ArrayList<>(); for (int i = 0; i < attachment.length; i++) { //获取附件信息 FieldSetEntity fseAttachment=baseDao.getFieldSetEntity("product_sys_attachments", attachment[i], false); if (fseAttachment!=null) { //获取附件 File file=fileManagerService.getFile(attachment[i]); if (file!=null) { //生成索引信息 Document doc=new Document(); doc.add(new StringField("uuid", attachment[i], Field.Store.YES)); //附件UUID doc.add(new TextField("service_uuid", service_uuid, Field.Store.YES)); //业务UUID doc.add(new TextField("function_uuid", function_uuid, Field.Store.YES)); //共嗯那个UUID doc.add(new TextField("file_name", fseAttachment.getString("file_name"), Field.Store.YES)); //文件名 doc.add(new TextField("file_content", FileUtils.FileToString(file), Field.Store.YES)); //文件内内容 docs.add(doc); } file.delete(); } } //写入索引 indexWriter.addDocuments(docs); indexWriter.commit(); } } } } } */ /** * 文档检索 * @param fse * @return * @throws Exception * @throws ParseException */ public JSONObject searchProduct(FieldSetEntity fse) throws Exception, ParseException { searcherManager.maybeRefresh(); IndexSearcher indexSearcher = searcherManager.acquire(); //文档信息汇总 List jsonTotal=new ArrayList<>(); JSONObject jsonReturn=new JSONObject(); // 模糊匹配,匹配词 String search_key=fse.getString("search_key"); if (!BaseUtil.strIsNull(search_key)) { //查询解析器 QueryParser parser = new MultiFieldQueryParser(new String [] {"file_name","file_content"}, new SmartChineseAnalyzer()); Query query = parser.parse(search_key); //高亮格式 SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("", ""); //高亮匹配器 Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query)); Fragmenter fragmenter = new SimpleFragmenter(100); highlighter.setTextFragmenter(fragmenter); //分页查询文档 TopDocs topDocs = searchByPage(fse.getInteger("cpage"), fse.getInteger("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("function_uuid"))) { getConfig(json, doc.get("function_uuid"), doc.get("uuid")); } json.put("function_uuid", doc.get("function_uuid")); // 内容增加高亮显示 String file_name=highlighter.getBestFragment(new SmartChineseAnalyzer(), "file_name",doc.get("file_name")); if (StringUtils.isEmpty(file_name)) { file_name=doc.get("file_name"); } String file_content=highlighter.getBestFragment(new SmartChineseAnalyzer(), "file_content",doc.get("file_content")); if (StringUtils.isEmpty(file_content)) { file_content=doc.get("file_content"); } json.put("file_name", file_name); json.put("file_content", file_content); jsonTotal.add(json); } jsonReturn.put("totalCount", topDocs.totalHits.value); } jsonReturn.put("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("product_sys_document_search", "function_uuid=?", new Object[] {function_uuid}, false); if (fseConfig!=null) { FieldSetEntity fseFunction=baseDao.getFieldSetEntity("product_sys_functions", function_uuid, false); //获取权限过滤字段 String org_fields=fseConfig.getString("org_fileds"); String user_fields=fseConfig.getString("user_fileds"); //获取附件信息 FieldSetEntity fseAttachment=baseDao.getFieldSetEntity("product_sys_attachments", uuid, false); baseDao.loadPromptData(fseAttachment); if (fseAttachment!=null) { StringBuilder filter=new StringBuilder(); filter.append(fseAttachment.getString("attachment_data_field")); filter.append(" =? "); if (StringUtils.isEmpty(org_fields)) { if (!StringUtils.isEmpty(user_fields)) { filter.append(" AND "); filter.append(permissionService.getDataFilter(fseAttachment.getString("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("attachment_data_table"), user_fields, org_fields)); } } //获取原数据 FieldSetEntity fseService=baseDao.getFieldSetEntityByFilter(fseAttachment.getString("attachment_data_table"), filter.toString(), new Object[] {uuid}, false); if (fseService==null) {//权限过滤无原数据 FieldSetEntity fseService2=baseDao.getFieldSetEntityByFilter(fseAttachment.getString("attachment_data_table"), fseAttachment.getString("attachment_data_field")+"=?", new Object[] {uuid}, false); if (fseService2==null) { // json.put("date_time", fseService2.getString(fseConfig.getString("time_field"))); json.put("title", "无相关业务数据"); json.put("function_name", fseFunction.getString("function_name")); json.put("is_perssion", 1); }else { json.put("service_uuid", fseService2.getString("uuid")); json.put("date_time", fseService2.getString(fseConfig.getString("time_field"))); json.put("title", fseService2.getString(fseConfig.getString("title_field"))); json.put("function_name", fseFunction.getString("function_name")); json.put("is_perssion", 0); } }else { json.put("service_uuid", fseService.getString("uuid")); json.put("date_time", fseService.getString(fseConfig.getString("time_field"))); json.put("title", fseService.getString(fseConfig.getString("title_field"))); json.put("function_name", fseFunction.getString("function_name")); } json.put("created_by", fseAttachment.getString(CmnConst.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(); } }