IndexSearcher indexSearcher = new IndexSearcher(LuceneUtils.getDirectory()); // 指定所用的索引库
这句会引发线程安全问题,在全剧终 IndexSearcher只能有一个对象才可以,所以在ArticleDocumentUtils中保存一个 并且引用它。
indexSearcher为了提高效率,也是在内存中有缓存的所以需要commit才能放入索引文件数据库中
数据库优化
每次添加数据在索引文件夹下有很多小文件,为了合并小文件提高效率
//优化,合并多个小文件为一个打文件
LuceneUtils.getIndexWriter.optimize();
//配置当小文件的数量达到多少个后就自动合并为一个大文件,最小2,默认10
LucenenUtils.getIndexWriter().setMergeFactor(3);
当增加数据的时候自动触发。
Lucene.java
1 package cn.itcast._util; 2 3 import java.io.File; 4 import java.io.IOException; 5 6 import org.apache.lucene.analysis.Analyzer; 7 import org.apache.lucene.analysis.standard.StandardAnalyzer; 8 import org.apache.lucene.index.CorruptIndexException; 9 import org.apache.lucene.index.IndexWriter; 10 import org.apache.lucene.index.IndexWriter.MaxFieldLength; 11 import org.apache.lucene.store.Directory; 12 import org.apache.lucene.store.FSDirectory; 13 import org.apache.lucene.store.LockObtainFailedException; 14 import org.apache.lucene.util.Version; 15 16 public class LuceneUtils { 17 18 private static Directory directory; // 索引库目录 19 private static Analyzer analyzer; // 分词器 20 21 private static IndexWriter indexWriter; 22 23 static { 24 try { 25 // 这里应是读取配置文件得到的索引库目录 26 directory = FSDirectory.open(new File("./indexDir")); 27 analyzer = new StandardAnalyzer(Version.LUCENE_30); 28 } catch (IOException e) { 29 throw new RuntimeException(e); 30 } 31 } 32 33 /** 34 * 获取全局唯一的IndexWriter对象 35 * 36 * @return 37 */ 38 public static IndexWriter getIndexWriter() { 39 // 在第一次使用IndexWriter是进行初始化 40 if (indexWriter == null) { 41 synchronized (LuceneUtils.class) { // 注意线程安全问题 42 if (indexWriter == null) { 43 try { 44 indexWriter = new IndexWriter(directory, analyzer, MaxFieldLength.LIMITED); 45 System.out.println("=== 已经初始化 IndexWriter ==="); 46 } catch (Exception e) { 47 throw new RuntimeException(e); 48 } 49 } 50 } 51 52 // 指定一段代码,会在JVM退出之前执行。 53 Runtime.getRuntime().addShutdownHook(new Thread() { 54 public void run() { 55 try { 56 indexWriter.close(); 57 System.out.println("=== 已经关闭 IndexWriter ==="); 58 } catch (Exception e) { 59 throw new RuntimeException(e); 60 } 61 } 62 }); 63 } 64 65 return indexWriter; 66 } 67 68 public static Directory getDirectory() { 69 return directory; 70 } 71 72 public static Analyzer getAnalyzer() { 73 return analyzer; 74 } 75 76 }
ArticleDocumentUtils.java
1 package cn.itcast._util; 2 3 import org.apache.lucene.document.Document; 4 import org.apache.lucene.document.Field; 5 import org.apache.lucene.document.Field.Index; 6 import org.apache.lucene.document.Field.Store; 7 import org.apache.lucene.util.NumericUtils; 8 9 import cn.itcast._domain.Article; 10 11 public class ArticleDocumentUtils { 12 13 /** 14 * 把Article转为Document 15 * 16 * @param article 17 * @return 18 */ 19 public static Document articleToDocument(Article article) { 20 Document doc = new Document(); 21 22 String idStr = NumericUtils.intToPrefixCoded(article.getId()); // 一定要使用Lucene的工具类把数字转为字符串! 23 24 doc.add(new Field("id", idStr, Store.YES, Index.NOT_ANALYZED)); // 注意:唯一标示符一般选择Index.NOT_ANALYZED 25 doc.add(new Field("title", article.getTitle(), Store.YES, Index.ANALYZED)); 26 doc.add(new Field("content", article.getContent(), Store.YES, Index.ANALYZED)); 27 28 return doc; 29 } 30 31 /** 32 * 把Document转为Article 33 * 34 * @param doc 35 * @return 36 */ 37 public static Article documentToArticle(Document doc) { 38 Article article = new Article(); 39 40 Integer id = NumericUtils.prefixCodedToInt(doc.get("id")); // 一定要使用Lucene的工具类把字符串转为数字! 41 42 article.setId(id); 43 article.setTitle(doc.get("title")); 44 article.setContent(doc.get("content")); 45 46 return article; 47 } 48 49 }