这里需要完成一个能对txt文本建立索引,并能完成检索查询。完成这个功能,使用的是Lucene4.5,同时使用其自带的中文分析器。
准备工作是在一个文件夹里面建一些txt文件,这是我的文件结构:
首先要对这些文本建立索引,代码如下
1 package com.test; 2 3 import java.io.*; 4 import java.util.ArrayList; 5 import java.util.List; 6 import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer; 7 import org.apache.lucene.document.*; 8 9 import org.apache.lucene.index.IndexWriter; 10 import org.apache.lucene.index.IndexWriterConfig; 11 import org.apache.lucene.store.Directory; 12 import org.apache.lucene.store.FSDirectory; 13 import org.apache.lucene.util.Version; 14 15 public class Indexer { 16 17 /** 18 * @param args 19 */ 20 21 private static String fileInput = "C:\Users\Press-Lab\Desktop\五月天歌词文件"; 22 //此处是索引存放的路径 23 private static String indexPath = "C:\Users\Press-Lab\Desktop\index"; 24 25 public static void main(String[] args) throws Exception { 26 // TODO Auto-generated method stub 27 //此处去处txt的内容和路径,装入list中,方便下一步放入document中 28 File[] files = new File(fileInput).listFiles(); 29 List<FileBag> list = new ArrayList<FileBag>(); 30 for(File f : files){ 31 BufferedReader br = new BufferedReader(new FileReader(f)); 32 StringBuffer sb = new StringBuffer(); 33 String line = null; 34 while((line = br.readLine()) != null){ 35 sb.append(line); 36 } 37 br.close(); 38 FileBag fileBag = new FileBag(); 39 fileBag.setContent(sb.toString()); 40 fileBag.setPath(f.getAbsolutePath()); 41 list.add(fileBag); 42 } 43 44 //此处为建立索引 45 Directory dir = FSDirectory.open(new File(indexPath)); 46 //此处使用自带的中文分析器 47 SmartChineseAnalyzer analyzer = new SmartChineseAnalyzer(Version.LUCENE_45); 48 IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_45, analyzer); 49 IndexWriter writer = new IndexWriter(dir, config); 50 51 //对list中的每一个对象,分别连击索引 52 for(FileBag fileBag : list){ 53 Document doc = new Document(); 54 doc.add(new Field("contents", fileBag.getContent(), Field.Store.YES,Field.Index.ANALYZED)); 55 doc.add(new StringField("path", fileBag.getPath(), Field.Store.YES)); 56 writer.addDocument(doc); 57 } 58 59 writer.close(); 60 61 } 62 63 } 64 //建立一个与txt对应的domain对象 65 class FileBag{ 66 private String content; 67 private String path; 68 public String getContent() { 69 return content; 70 } 71 public void setContent(String content) { 72 this.content = content; 73 } 74 public String getPath() { 75 return path; 76 } 77 public void setPath(String path) { 78 this.path = path; 79 } 80 81 82 }
在这段代码中,我对文本进行了存储,一般情况下是无需存储的,这里为为了方便查看结果才进行存储。
特别注意代码的54行,如果使用Lucene4.5推荐的TextField,这无法建立索引。不知道这是个什么原因,有人解决过这个问题的麻烦告知下。
下面是进行检索的代码:
1 package com.test; 2 3 import java.io.*; 4 5 import org.apache.lucene.analysis.Analyzer; 6 import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer; 7 import org.apache.lucene.analysis.standard.StandardAnalyzer; 8 import org.apache.lucene.document.Document; 9 import org.apache.lucene.index.DirectoryReader; 10 import org.apache.lucene.index.IndexReader; 11 import org.apache.lucene.index.Term; 12 13 14 import org.apache.lucene.queryparser.classic.QueryParser; 15 import org.apache.lucene.search.IndexSearcher; 16 17 import org.apache.lucene.search.Query; 18 import org.apache.lucene.search.ScoreDoc; 19 import org.apache.lucene.search.TermQuery; 20 import org.apache.lucene.search.TopDocs; 21 import org.apache.lucene.store.Directory; 22 import org.apache.lucene.store.FSDirectory; 23 import org.apache.lucene.util.Version; 24 25 import com.dong.Constants; 26 27 public class Seacher { 28 29 /** 30 * @param args 31 */ 32 private static String indexPath = "C:\Users\Press-Lab\Desktop\index"; 33 public static void main(String[] args) throws Exception { 34 // TODO Auto-generated method stub 35 36 Directory dir=FSDirectory.open(new File(indexPath)); 37 IndexReader reader=DirectoryReader.open(dir); 38 IndexSearcher searcher=new IndexSearcher(reader); 39 //此处也需要是用中文分析器 40 SmartChineseAnalyzer analyzer = new SmartChineseAnalyzer(Version.LUCENE_45); 41 QueryParser parser = new QueryParser(Version.LUCENE_45, "contents", analyzer); 42 Query query = parser.parse("如果") ; 43 44 TopDocs topdocs=searcher.search(query, 5); 45 ScoreDoc[] scoreDocs=topdocs.scoreDocs; 46 47 System.out.println("共有数据:" + topdocs.scoreDocs.length + "条"); 48 for(int i=0; i < scoreDocs.length; i++) { 49 int doc = scoreDocs[i].doc; 50 Document document = searcher.doc(doc); 51 System.out.println("第" + i + "条文本的路径是: " + document.get("path")); 52 System.out.println("第" + i + "条文本内容是: " + document.get("contents")); 53 54 } 55 reader.close(); 56 } 57 58 59 60 61 }
这里需要注意的是,查询时候也需要中文分析器。
下一篇要做的是,实现索引的分页查询。