package cn.richinfo.cmail.basemail.common.tools; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.IntField; import org.apache.lucene.document.StringField; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.IndexWriterConfig.OpenMode; import org.apache.lucene.index.Term; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.TopDocs; import org.apache.lucene.search.WildcardQuery; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import org.apache.lucene.util.Version; import cn.richinfo.cmail.basemail.addr.model.LuceneEngineModel; import cn.richinfo.cmail.common.log.CommonLogger; import cn.richinfo.cmail.common.log.Log; public class LuceneEngineUtil { private static final Log log = CommonLogger.getInstance(); /** * 清空旧索引文件 * @param path */ public static void delFiles(String path) { File file = new File(path); if (file.exists() && file.isDirectory() && file.list().length > 0) { log.info("delete file " + path); File[] files = file.listFiles(); for (int i = 0; i < files.length; i++) { if (!files[i].isFile()) { delFiles(files[i].getAbsolutePath()); } files[i].delete(); } } } private static IndexWriter getIndexWriter(String path) throws Exception { Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_40); IndexWriterConfig conf = new IndexWriterConfig(Version.LUCENE_40, analyzer); conf.setOpenMode(OpenMode.CREATE_OR_APPEND); conf.setMaxBufferedDocs(100); Directory directory = FSDirectory.open(new File(path)); return new IndexWriter(directory, conf); } private static IndexReader getIndexReader(String path) throws Exception { Directory directory = FSDirectory.open(new File(path)); return DirectoryReader.open(directory); } /** * 创建索引 * * @param path * @param model */ public static void createIndex(String path, LuceneEngineModel model) { log.info("create index: path=" + path); IndexWriter writer = null; try { writer = getIndexWriter(path); writer.addDocument(toDocument(model)); log.info("create index success."); } catch (Exception e) { log.error("create index fail: ", new Exception(e)); } finally { try { if (writer != null) { log.info("writer close……"); writer.close(); } } catch (Exception e) { e.printStackTrace(); } } } /** * 创建索引 * * @param path * @param list */ public static void createIndex(String path, List<LuceneEngineModel> list) { log.info(String.format("create index batch: path=%s | size=%s", path, list.size())); IndexWriter writer = null; long start = System.currentTimeMillis(); try { writer = getIndexWriter(path); for (int i = 0; i < list.size(); i++) { writer.addDocument(toDocument(list.get(i))); } log.info(String.format("create index batch success : time=%sms", (System.currentTimeMillis() - start))); } catch (Exception e) { log.error("create index batch fail: ", new Exception(e)); } finally { try { if (writer != null) { log.info("writer close……"); writer.close(); } } catch (Exception e) { e.printStackTrace(); } } } private static Document toDocument(LuceneEngineModel model) { Document document = new Document(); if (model != null) { log.info("addDocument: " + model.toString()); document.add(new IntField("type", model.getType(), Field.Store.YES)); document.add(new IntField("id", model.getId(), Field.Store.YES)); document.add(new StringField("email", formatNull(model.getEmail()), Field.Store.YES)); document.add(new StringField("mobile", formatNull(model.getMobile()), Field.Store.YES)); document.add(new StringField("first_name", formatNull(model.getFirst_name()), Field.Store.YES)); document.add(new StringField("second_name", formatNull(model.getSecond_name()), Field.Store.YES)); document.add(new StringField("position", formatNull(model.getPosition()), Field.Store.YES)); document.add(new StringField("locate_name_list", formatNull(model.getLocate_name_string()), Field.Store.YES)); document.add(new StringField("dept_list", formatNull(model.getDept_list()), Field.Store.YES)); } return document; } private static String formatNull(String value) { if (value == null) return ""; return value; } /** * 删除索引 * * @param path * @param email */ public static void deleteIndex(String path, String email) { log.info(String.format("delete index: path=%s | email=%s", path, email)); IndexWriter writer = null; try { writer = getIndexWriter(path); Term term = new Term("email", email); writer.deleteDocuments(term); log.info("delete index success."); } catch (Exception e) { log.error("delete index fail: ", new Exception(e)); } finally { try { if (writer != null) { log.info("writer close……"); writer.close(); } } catch (Exception e) { e.printStackTrace(); } } } /** * 更新索引 * * @param path * @param email * @param model */ public static void updateIndex(String path, String email, LuceneEngineModel model) { log.info(String.format("update index: path=%s | email=%s", path, email)); IndexWriter writer = null; try { writer = getIndexWriter(path); Term term = new Term("email", email); writer.updateDocument(term, toDocument(model)); log.info("update index success."); } catch (Exception e) { log.error("update index fail: ", new Exception(e)); } finally { try { if (writer != null) { log.info("writer close……"); writer.close(); } } catch (Exception e) { e.printStackTrace(); } } } public static List<LuceneEngineModel> searchDeptIndex(String path, String deptId) { log.info(String.format("search index: path=%s | deptId=[%s]", path, deptId)); List<LuceneEngineModel> list = new ArrayList<LuceneEngineModel>(); IndexReader reader = null; long start = System.currentTimeMillis(); try { reader = getIndexReader(path); IndexSearcher searcher = new IndexSearcher(reader); Term term = new Term("dept_list", deptId); Query query = new WildcardQuery(term); TopDocs tds = searcher.search(query, 20); for (ScoreDoc sd : tds.scoreDocs) { Document doc = searcher.doc(sd.doc); list.add(toEntity(doc)); } log.info(String.format("search index success: size=%s | time=%sms", tds.totalHits, (System.currentTimeMillis() - start))); } catch (Exception e) { log.error("search index fail: ", new Exception(e)); } finally { try { if (reader != null) { log.info("reader close……"); reader.close(); } } catch (Exception e) { e.printStackTrace(); } } return list; } /** * 检索索引 * * @param path * @param content * @param total * @return * @throws Exception */ public static List<LuceneEngineModel> searchIndex(String path, String content, String total) { log.info(String.format("search index: path=%s | content=[%s] | total=%s", path, content, total)); List<LuceneEngineModel> list = new ArrayList<LuceneEngineModel>(); IndexReader reader = null; long start = System.currentTimeMillis(); try { reader = getIndexReader(path); IndexSearcher searcher = new IndexSearcher(reader); Term term = new Term("email", "*" + content + "*"); Query query = new WildcardQuery(term); TopDocs tds = searcher.search(query, Integer.parseInt(total)); log.info(String.format("search index success: size=%s | time=%sms", tds.totalHits, (System.currentTimeMillis() - start))); for (ScoreDoc sd : tds.scoreDocs) { Document doc = searcher.doc(sd.doc); list.add(toEntity(doc)); } } catch (Exception e) { log.error("search index fail: ", new Exception(e)); } finally { try { if (reader != null) { log.info("reader close……"); reader.close(); } } catch (Exception e) { e.printStackTrace(); } } return list; } private static LuceneEngineModel toEntity(Document doc) { LuceneEngineModel model = new LuceneEngineModel(); model.setType(Integer.parseInt(doc.get("type"))); model.setId(Integer.parseInt(doc.get("id"))); model.setEmail(doc.get("email")); model.setMobile(doc.get("mobile")); model.setFirst_name(doc.get("first_name")); model.setSecond_name(doc.get("second_name")); model.setPosition(doc.get("position")); String array[] = doc.get("locate_name_list").split(","); model.setLocate_name_list(Arrays.asList(array)); return model; } }