版权声明:欢迎转载,若有不当之处请在评论中指出,共同交流。 https://blog.csdn.net/qq_33290787/article/details/52190500
本文将给出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对象为待搜索的文档创建索引文件:
// 创建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) {
// 创建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");
}
}
运行结果:
查找到的文档总共有:2
hhh.txt C:\Users\Administrator\Desktop\File\hhh.txt
今天是2016年8月12号。开始总结Lucene了,并且打算运用Lucene至项目中
<font color="red">今</font><font color="red">天</font>是2016年8月12号。开始<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