好久好久,终于又写了这么一篇博客。时隔一年啊,这一年经历了一些有关编码没关编码的事,哈哈,在这儿就不多说了。这篇博客主要介绍lucene的入门小姐。
为什么要入手lucene呢,是网上看到网络爬虫,爬着各种东西,瞬间觉得这东西碉堡了,于是跑去图书馆,找来了一本关于搜索引擎的书,于是照着抄代码,wokao,lucene更新换代的速度还是蛮快而且变化蛮大的。所以书上的代码还是要查阅很多资料才可以明白并实现。下面就是创建索引还有搜索的小实例。
首先是先建立几个txt文件,来创建索引。文件里面也就几个英文单词而已
其次简历索引,代码如下
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.SimpleFSDirectory;
import org.apache.lucene.util.Version;
public class IndexProcessor {
public static String index_store_path = "F:\\2013summer搜索引擎\\index\\prac2013_07_26";
private IndexWriter writer;
private Analyzer analyzer=new StandardAnalyzer(Version.LUCENE_43);
public void createIndex(String filePath,String openDir) throws IOException {
try {
//使用工厂函数创建directory实例
Directory d = SimpleFSDirectory.open(new File(filePath));
IndexWriterConfig config=new IndexWriterConfig(Version.LUCENE_43, analyzer);
writer = new IndexWriter(d, config);
config.setOpenMode(OpenMode.CREATE);
writeIndex(openDir);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Document getDocument(File f){
if(!f.getName().endsWith(".txt")){
return null;
}
try {
Document doc=new Document();
InputStream is=new FileInputStream(f);
BufferedReader reader=new BufferedReader(new InputStreamReader(is));
//两个field,然后加到document里面。document其实也就是管理field的。
Field pathField = new StringField("path", f.getAbsolutePath(),Field.Store.YES);
Field contenField = new TextField("contents", reader);
doc.add(pathField);
doc.add(contenField);
return doc;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return null;
}
public void writeIndex(String openDir) throws IOException{
File f=new File(openDir);
//如果是文件夹
if(f.isDirectory()){
String[] temp=f.list();
for(int i=0;i<temp.length;i++){
File file=new File(f,temp[i]);
Document doc=getDocument(file);
System.out.println("正在建立索引 : " + file + "");
if(null!=doc){
writer.addDocument(doc);
}
}
}
}
public void close() throws Exception {
writer.close();
}
public static void main(String[] args) {
IndexProcessor index=new IndexProcessor();
try {
index.createIndex(index_store_path, "F:\\2013summer搜索引擎\\test");
//注意:一定要close,不close的话,那么在内存中出不来,索引是建立不好的
index.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
analyzer我选择standardanalyzer,对于以上一些细节部分,会在今后说明。说明一点的是,如果没有close的话,那么索引没有建立好是会上锁的,在文件夹里会有一个write.lock文件。
接下来是搜索实例:
import java.io.File;
import java.util.Date;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
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.store.SimpleFSDirectory;
import org.apache.lucene.util.Version;
public class SearchTool {
// 声明一个IndexSearcher对象
private IndexSearcher searcher = null;
// 声明一个Query对象
private Query query = null;
private String field = "contents";
public SearchTool() {
try {
IndexReader reader = DirectoryReader.open(SimpleFSDirectory.open(new File("F:\\2013summer搜索引擎\\index\\prac2013_07_26")));
searcher = new IndexSearcher(reader);
} catch (Exception e) {
e.printStackTrace();
}
}
//返回查询结果
public final TopDocs search(String keyword) {
System.out.println("正在检索关键字 : " + keyword);
try {
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_43);
QueryParser parser = new QueryParser(Version.LUCENE_43, field,analyzer);
// 将关键字包装成Query对象
query = parser.parse(keyword);
Date start = new Date();
TopDocs results = searcher.search(query, 5 * 2);
Date end = new Date();
System.out.println("检索完成,用时" + (end.getTime() - start.getTime())
+ "毫秒");
return results;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
//打印结果
public void printResult(TopDocs results) {
ScoreDoc[] h = results.scoreDocs;
if (h.length == 0) {
System.out.println("对不起,没有找到您要的结果。");
} else {
for (int i = 0; i < h.length; i++) {
try {
Document doc = searcher.doc(h[i].doc);
System.out.print("这是第" + i + "个检索到的结果,文件名为:");
System.out.println(doc.get("path"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
System.out.println("--------------------------");
}
public static void main(String[] args) throws Exception {
SearchTool test = new SearchTool();
TopDocs h = null;
h = test.search("haha");
test.printResult(h);
}
}
最后的结果是:
正在检索关键字 : haha
检索完成,用时855毫秒
这是第0个检索到的结果,文件名为:F:\2013summer搜索引擎\test\2.txt
这是第1个检索到的结果,文件名为:F:\2013summer搜索引擎\test\lu.txt
--------------------------
正解,接下来关于lucene的搜索还会有篇幅来介绍。