Lucene 是一个基于 Java 的全文信息检索工具包,它不是一个完整的搜索应用程序,而是为你的应用程序提供索引和搜索功能。Lucene 目前是 Apache Jakarta 家族中的一个开源项目。也是目前最为流行的基于 Java 开源全文检索工具包。java
目前已经有不少应用程序的搜索功能是基于 Lucene 的,好比 Eclipse 的帮助系统的搜索功能。Lucene 可以为文本类型的数据创建索引,因此你只要能把你要索引的数据格式转化的文本的,Lucene 就能对你的文档进行索引和搜索。好比你要对一些 HTML 文档,PDF 文档进行索引的话你就首先须要把 HTML 文档和 PDF 文档转化成文本格式的,而后将转化后的内容交给 Lucene 进行索引,而后把建立好的索引文件保存到磁盘或者内存中,最后根据用户输入的查询条件在索引文件上进行查询。不指定要索引的文档的格式也使 Lucene 可以几乎适用于全部的搜索应用程序。apache
package com.demo.index; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.nio.file.FileSystems; import java.util.logging.Logger; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field.Store; import org.apache.lucene.document.TextField; import org.apache.lucene.index.*; import org.apache.lucene.index.IndexWriterConfig.OpenMode; import org.apache.lucene.queryparser.classic.QueryParser; import org.apache.lucene.search.*; import org.apache.lucene.store.*; public class LuceneIndex { private static Logger logger = Logger.getLogger(LuceneIndex.class.getName()); //IndexWriter 索引文件的segment进行写、合并、优化 IndexWriter indexWriter; //将要存储索引的目录 Directory dir; public LuceneIndex(){ try{ IndexWriterConfig config = new IndexWriterConfig(new StandardAnalyzer()); config.setOpenMode(OpenMode.CREATE_OR_APPEND); this.dir = new RAMDirectory(); this.indexWriter = new IndexWriter(dir,config); }catch (Exception e){ e.printStackTrace(); } } //索引保存于内存中 public LuceneIndex(String dataUrl){ try{ IndexWriterConfig config = new IndexWriterConfig(new StandardAnalyzer()); config.setOpenMode(OpenMode.CREATE_OR_APPEND); this.dir = new RAMDirectory(); this.indexWriter = new IndexWriter(this.dir,config); //根据传入的URL添加索引 addDocument(dataUrl); closeWriter(); }catch (Exception e){ e.printStackTrace(); } } //索引保存于指定目录 public LuceneIndex(String IndexUrl,String dataUrl){ try{ IndexWriterConfig config = new IndexWriterConfig(new StandardAnalyzer()); config.setOpenMode(OpenMode.CREATE_OR_APPEND); this.dir = FSDirectory.open(FileSystems.getDefault().getPath(IndexUrl)); this.indexWriter = new IndexWriter(dir,config); //根据传入的URL添加索引 addDocument(dataUrl); closeWriter(); }catch (Exception e){ e.printStackTrace(); } } public void closeWriter(){ try { this.indexWriter.close(); } catch (IOException e) { e.printStackTrace(); } } /** * 根据提供的URL添加索引,但是文档或者目录 * @param url 文件或者目录 */ public void addDocument(String url){ try{ File file = new File(url); if(file.exists()){ if(file.isFile()){ Document document = getDocument(file); this.indexWriter.addDocument(document); }else if(file.isDirectory()){ //File[] dataFiles = new File("/Users/wangjing/Documents/lucene/data/").listFiles(); File[] dataFiles = file.listFiles(); if(dataFiles != null){ for(File f : dataFiles) { if (f.isFile() && f.getName().endsWith(".txt")) { System.out.println("正在创建索引:" + f.getCanonicalPath()); //生成Document Document document = getDocument(f); this.indexWriter.addDocument(document); } } }else{ logger.info("找不到目录"); } } this.indexWriter.commit(); }else{ logger.info("找不到文件或者目录"); } }catch (Exception e){ e.printStackTrace(); } } /** * 根据file生成Document * @param file 文件 * @return 文档结构 */ public Document getDocument(File file){ Document document = new Document(); //document.add(new StringField("path", dataFiles[i].getAbsolutePath(),Store.YES)); document.add(new TextField("path", file.getAbsolutePath(),Store.YES)); document.add(new TextField("contents", getFileContent(file),Store.YES)); return document; } /** * 获取文件内容 * @param file 文件 * @return 文件内容 */ public static String getFileContent(File file){ String result = ""; try{ BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件 String s; while((s = br.readLine())!=null){//使用readLine方法,一次读一行 result = result+s; } br.close(); }catch(Exception e){ e.printStackTrace(); } return result; } /** * 根据字段以及值进行查找 * @param field 字段 * @param queryString 值 */ public void search(String field , String queryString){ try{ IndexReader reader = DirectoryReader.open(this.dir); IndexSearcher searcher = new IndexSearcher(reader); // Term term = new Term(field,queryString); // TermQuery luceneQuery = new TermQuery(term); Query query = new QueryParser(field,new StandardAnalyzer()).parse(queryString); TopDocs result = searcher.search(query,10); ScoreDoc[] hits = result.scoreDocs; System.out.println("找到" + hits.length + "条记录"); for(int i=0;i<hits.length;++i) { int docId = hits[i].doc; Document d = searcher.doc(docId); System.out.println((i + 1) + ". " + d.get("path") + "\t" + d.get("contents")); } }catch (Exception e){ e.printStackTrace(); } } public static void main(String[] args) { LuceneIndex index = new LuceneIndex("/Users/wangjing/Documents/lucene/data1/"); index.search("contents","国"); } }