首先,先看下目录结构。
第一步,在 eclipse 中建立 jave 项目。需要引入 jar 包,只有 3 个,分别是 lucene 的分词器和核心包,还有高亮显示器。做法是建立一个 lib 文件夹,将 jar 包拷过来,然后右击,选择 Build Path (构建路径), Addto Build Path (添加到项目的构建路径)。
然后建立 datasource 文件夹,添几个 txt 的文件进去,内容爱写啥写啥。(但是建议是一个是中文,一个是英文,可以测两种语言的分词)。还有 luceneIndex 文件夹 , 用来存放创建的索引 .
其中 , IndexWriteraddDocument's a javadoc .txt 的内容是
Adds room adocument to this room index. If the room document contains room more than setMaxFieldLength(int) terms for agiven field, the remainder are discarded.
小笑话 _ 总统的房间 Room .txt 的内容是
总统的房间
一位绅士到旅游胜地的一家饭店要开个房间,
侍者因为他没有预定而拒绝说:“房间全满,无法安排。”
“ 听着!”绅士说,“假如我告诉你总统要到这里来,你一定会马上向他提供一套客房吧?”
“ 当然啦,他是总……”
“ 好了,我荣幸地通知你:总统今晚不来了。你把他的房间给我吧!”
然后建立包, com.lucene.helloworld ,新建一个 HelloWorld 的类。里面主要的两个方法就是建立索引,以及查询关键字。
package com.lucene.helloworld; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriter.MaxFieldLength; import org.apache.lucene.queryParser.MultiFieldQueryParser; import org.apache.lucene.queryParser.QueryParser; import org.apache.lucene.search.Filter; 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.junit.Test; import com.lucene.units.File2DocumentUtils; public class HelloWorld { String filePath = "F:\\Users\\liuyanling\\workspace\\LuceneDemo\\datasource\\peoplewhocannot.txt" ; String indexPath = "F:\\Users\\liuyanling\\workspace\\LuceneDemo\\luceneIndex" ; Analyzer analyzer = new StandardAnalyzer(); @Test public void createIndex() throws Exception { Document doc = File2DocumentUtils.file2Document(filePath); IndexWriter indexWriter = new IndexWriter(indexPath,analyzer, true ,MaxFieldLength.LIMITED); indexWriter.addDocument(doc); indexWriter.close(); } @Test public void search() throws Exception { String queryString = "Internet" ; String[] fields = {"name" , "content" }; QueryParser queryParser = new MultiFieldQueryParser(fields,analyzer); Query query = queryParser.parse(queryString); IndexSearcher indexSearcher = new IndexSearcher(indexPath); Filter filter = null ; TopDocs topDocs = indexSearcher.search(query,filter,10000 ); System.out.println("总共有[" +topDocs.totalHits+ "]条匹配结果" ); for (ScoreDoc scoreDoc : topDocs.scoreDocs ) { int docSn = scoreDoc.doc; Document doc = indexSearcher.doc(docSn); File2DocumentUtils.printDocumentInfo(doc); }; } }
接着,由于里面用了 File2DocumentUtils 类的 printDocumentInfo () 和 file2Document( ) ,打印 Document 内容和 File 转换为 Document 两个方法。看看 File2DocummentUtils 文件内容 .
package com.lucene.units; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStreamReader; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.NumberTools; import org.apache.lucene.document.Field.Index; import org.apache.lucene.document.Field.Store; public class File2DocumentUtils { public static Document file2Document(String path) { File file = new File(path); Document doc = new Document(); doc.add(new Field( "name" ,file.getName(),Store.YES,Index.ANALYZED)); doc.add(new Field( "content" ,readFileContent(file),Store.YES,Index.ANALYZED)); doc.add(new Field( "size" ,String.valueOf(file.length()),Store.YES,Index.NOT_ANALYZED)); doc.add(new Field( "path" ,file.getPath(),Store.YES,Index.NO)); return doc; } public static String readFileContent(File file) { try { BufferedReader reader = new BufferedReader ( new InputStreamReader( new FileInputStream(file))); StringBuffer content = new StringBuffer(); for (String line = null ;(line = reader.readLine()) != null ;) { content.append(line).append("\n" ); } return content.toString(); } catch (Exception e) { throw new RuntimeException(); } } public static void printDocumentInfo(Document doc) { System.out.println("name =" +doc.get( "name" )); System.out.println("content =" +doc.get( "content" )); System.out.println("size =" +doc.get( "size" )); System.out.println("path =" +doc.get( "path" )); } }
代码写完了,先创建索引,在 createIndex 方法上右击 Run As 选择 Junit Test ,进行单元测试 。
测试成功之后,就可以看到 index 增加了,说明索引添加了。
然后测试测试,查询的结果如下。只查询到一个结果,将 name , context , size 和路径都打印出来了。
以上就是简单的全文检索查询,缺陷有很多,比如索引的存放位置是事先手动创建的,比如没有进行查询结果的高亮设置,比如对于分词器也只使用了标准的分词器。所以,改进请见下篇《全文检索之
lucene
的优化篇
--
创建索引存放的目录》.