初识Lucene(下)

来源:互联网 发布:java 字符串转10进制 编辑:程序博客网 时间:2024/05/16 01:19

本文将给出Lucene 6.1.0的代码实现与讲解。请确保已经阅读:初始Lucene(上)。Lucene从最初的1.9.1更新到现在的6.1.0。在这个过程中一些接口已经被弃用,也有新功能的加入,因此不同版本的Lucene代码实现方式可能是不一样的,具体版本的代码实现可以查看官方文档Lucene 6.1.0 API,这是6.1.0版本的使用文档。


项目开始之前,要进行Lucene 6.1.0相关jar包的导入,jar包下载地址http://lucene.apache.org/core/index.html:

这里写图片描述

步骤一:创建一个IndexWriter对象为待搜索的文档创建索引文件:

// 创建DirectoryDirectory directory = FSDirectory.open( FileSystems.getDefault().getPath("C:/Users/Administrator/Desktop/LuceneIndex"));// 创建IndexWriterAnalyzer analyzer = new StandardAnalyzer();IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);indexWriter = new IndexWriter(directory, indexWriterConfig);indexWriter.deleteAll();//清空以前的index

步骤二:打开硬盘中的文件,读取文件中的内容,创建索引文件:

//要搜索的File路径,路径下全是后缀名为.txt的文档File dFile = new File("C:/Users/Administrator/Desktop/File");File[] files = dFile.listFiles();for (File file : files) {    // 创建Document对象    Document document = new Document();    // 为Document添加Field               document.add(new Field("content",content,TextField.TYPE_STORED));    document.add(new Field("filename", file.getName(), TextField.TYPE_STORED));    document.add(new Field("filepath", file.getAbsolutePath(), TextField.TYPE_STORED));    // 通过IndexWriter添加文档到索引中    indexWriter.addDocument(document);    /*其实Document对象相当于数据库中的表,为它添加的Field(域)相当于数据表中的字段。在写入索引     * 文件indexWriter.addDocument(document)操作时,相当于为单词词库中的关键词建立相     * 应倒排文件的指针,产生一种映射关系。在这里"content"域静态变量可以设置为TYPE_NOT_STORED,     * 因为倒排文件已经保存了"filepath",搜索过后可以通过路径再到硬盘中得到文本内容。*/}

经过步骤一与步骤二,已经完成为待搜索文件创建索引的工作,下面就开始搜索。

步骤三:搜索文本时,创建IndexSearch索引搜索对象:

// 创建Directory  Directory directory = FSDirectory.open( FileSystems.getDefault().getPath("C:/Users/Administrator/Desktop/LuceneIndex"));// 创建IndexReader  directoryReader = DirectoryReader.open(directory);  // 根据IndexReader创建IndexSearch  IndexSearcher indexSearcher = new IndexSearcher(directoryReader);

步骤四:创建Query对象:

// 创建搜索的Query  Analyzer analyzer = new StandardAnalyzer();  // 创建parser来确定要搜索文件的内容,第一个参数为搜索的域  QueryParser queryParser = new QueryParser("content", analyzer);  // 创建Query表示搜索域为content包含keyWord的文档  Query query = queryParser.parse(keyWord); 

步骤五:得到搜索结果与代码高亮:

// 根据searcher搜索并且返回TopDocs  TopDocs topDocs = indexSearcher.search(query, 1000);  System.out.println("查找到的文档总共有:"+topDocs.totalHits);// 根据TopDocs获取ScoreDoc对象  ScoreDoc[] scoreDocs = topDocs.scoreDocs;  for (ScoreDoc scoreDoc : scoreDocs) {      // 根据searcher和ScoreDoc对象获取具体的Document对象      Document document = indexSearcher.doc(scoreDoc.doc);      // 根据Document对象获取需要的值      System.out.println(document.get("filename") + " " + document.get("filepath"));     System.out.println(document.get("content"));//得到搜索结果    String value = toHighlighter(query,document,"content",analyzer);    System.out.println(value);//得到搜索结果,带有关键词高亮}

完整代码:

package HighLightSearch;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileOutputStream;import java.io.OutputStreamWriter;import java.io.File;import java.io.FileReader;import java.io.IOException;import java.io.StringReader;import java.nio.file.FileSystems;import org.apache.lucene.analysis.Analyzer;import org.apache.lucene.analysis.TokenStream;import org.apache.lucene.analysis.standard.StandardAnalyzer;import org.apache.lucene.document.Document;import org.apache.lucene.document.Field;import org.apache.lucene.document.TextField;import org.apache.lucene.index.DirectoryReader;import org.apache.lucene.index.IndexWriter;import org.apache.lucene.index.IndexWriterConfig;import org.apache.lucene.queryparser.classic.QueryParser;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.highlight.Highlighter;import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;import org.apache.lucene.search.highlight.QueryScorer;import org.apache.lucene.search.highlight.SimpleHTMLFormatter;import org.apache.lucene.store.Directory;import org.apache.lucene.store.FSDirectory;class Index {    // 建立索引    public void index() {        IndexWriter indexWriter = null;        try {            // 创建Directory            Directory directory = FSDirectory.open(                    FileSystems.getDefault().getPath("C:/Users/Administrator/Desktop/LuceneIndex"));            // 创建IndexWriter            Analyzer analyzer = new StandardAnalyzer();            IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);            indexWriter = new IndexWriter(directory, indexWriterConfig);            indexWriter.deleteAll();//清除以前的index            //要搜索的File路径,路径下全是后缀名为.txt的文档            File dFile = new File("C:/Users/Administrator/Desktop/File");            File[] files = dFile.listFiles();            for (File file : files) {                //读取文档中的内容至content字符串中                 BufferedReader in = new BufferedReader(new FileReader(file));                  String s;                 String content = "";                 while((s = in.readLine()) != null){//readLine()方法每次读取文件的一行直到遇到换行符                     content += s+"\n";                 }                 in.close();                 File outputFile = new File("C:/Users/Administrator/Desktop/LuceneOutput/"+file.getName());                 if(!outputFile.exists()){                     System.out.print("创建文件:"+file.getName());                     outputFile.createNewFile();                 }                 //将字符串的内容写入输出文档中                 BufferedWriter bw = new BufferedWriter(                         new OutputStreamWriter(                                 new FileOutputStream("C:/Users/Administrator/Desktop/LuceneOutput/"+file.getName())));                 bw.write(content);                 bw.close();                // 创建Document对象                Document document = new Document();                // 为Document添加Field                           document.add(new Field("content",content, TextField.TYPE_STORED));                document.add(new Field("filename", file.getName(), TextField.TYPE_STORED));                document.add(new Field("filepath", file.getAbsolutePath(), TextField.TYPE_STORED));                // 通过IndexWriter添加文档到索引中                indexWriter.addDocument(document);            }        } catch (Exception e) {            e.printStackTrace();        } finally {            try {                if (indexWriter != null) {                    indexWriter.close();                }            } catch (Exception e) {                e.printStackTrace();            }        }    }}class Search {      public void search(String keyWord) {          DirectoryReader directoryReader = null;          try {              // 创建Directory              Directory directory = FSDirectory.open(                    FileSystems.getDefault().getPath("C:/Users/Administrator/Desktop/LuceneIndex"));            // 创建IndexReader              directoryReader = DirectoryReader.open(directory);              // 根据IndexReader创建IndexSearch              IndexSearcher indexSearcher = new IndexSearcher(directoryReader);              // 创建搜索的Query              Analyzer analyzer = new StandardAnalyzer();              // 创建parser来确定要搜索文件的内容,第一个参数为搜索的域              QueryParser queryParser = new QueryParser("content", analyzer);              // 创建Query表示搜索域为content包含UIMA的文档              Query query = queryParser.parse(keyWord);              // 根据searcher搜索并且返回TopDocs              TopDocs topDocs = indexSearcher.search(query, 1000);              System.out.println("查找到的文档总共有:"+topDocs.totalHits);            // 根据TopDocs获取ScoreDoc对象              ScoreDoc[] scoreDocs = topDocs.scoreDocs;              for (ScoreDoc scoreDoc : scoreDocs) {                  // 根据searcher和ScoreDoc对象获取具体的Document对象                  Document document = indexSearcher.doc(scoreDoc.doc);                  // 根据Document对象获取需要的值                  System.out.println(document.get("filename") + " " + document.get("filepath"));                 System.out.println(document.get("content"));//得到搜索结果                String value = toHighlighter(query,document,"content",analyzer);                System.out.println(value);//得到搜索结果,带有关键词高亮            }          } catch (Exception e) {              e.printStackTrace();          } finally {              try {                  if (directoryReader != null) {                      directoryReader.close();                  }              } catch (Exception e) {                  e.printStackTrace();              }          }      }    //高亮    public String toHighlighter(Query query,Document doc,String field,Analyzer analyzer){        try {            SimpleHTMLFormatter simpleHtmlFormatter = new SimpleHTMLFormatter("<font color=\"red\">", "</font>");            Highlighter highlighter = new Highlighter(simpleHtmlFormatter,new QueryScorer(query));            TokenStream tokenStream1 = analyzer.tokenStream("text",new StringReader(doc.get(field)));            String highlighterStr = highlighter.getBestFragment(tokenStream1, doc.get(field));            return highlighterStr == null ? doc.get(field):highlighterStr;        } catch (IOException e) {            e.printStackTrace();            return null;        } catch (InvalidTokenOffsetsException e) {            e.printStackTrace();            return null;        }    }}  public class HighLightSearch {    //测试    public static void main(String[] args) {        Index newIndex = new Index();        newIndex.index();        Search newSearch = new Search();        newSearch.search("今天总结Lucene");    }}

运行结果:

查找到的文档总共有:2hhh.txt C:\Users\Administrator\Desktop\File\hhh.txt今天是2016812号。开始总结Lucene了,并且打算运用Lucene至项目中<font color="red">今</font><font color="red">天</font>是2016812号。开始<font color="red">总</font><font color="red">结</font><font color="red">Lucene</font>了,并且打算运用<font color="red">Lucene</font>至项目中goal.txt C:\Users\Administrator\Desktop\File\goal.txt数据库Spring+SpringMVC+MyBatis+Maven(项目)常用算法(数据结构)CSS3(JS,node.js)数据库Spring+SpringMVC+MyBatis+Maven(项目)常用算法(数据<font color="red">结</font>构)CSS3(JS,node.js)

项目源码地址,欢迎Fork与Star~:

https://github.com/HuangFuGui/Javaweb/tree/master/LuceneProject


1 0
原创粉丝点击