获得Lucene
在apache网站下载最新的lucene包:http://www.apache.org/dyn/closer.cgi/lucene/java/, 本案我下载的是lucene-2.9.0.zip,解压之后文件结构如下:
我有必要解释一下,因为我觉得我在这里走了一点弯路,contrib目录放的都是配套jar包, 包括词法分析, 查询分析, 高亮显示等等,docs里面的文档很重要,因为我发现lucene2.9变化很大, 很多类和方法都有较大的改变, 然而lucene又没有很好的翻译的资料,所以看原始的文档还是很重要的。src目录里面包含了几个demo,他们都很有用,值得看。
新建一个project
新建一个web project,并把如下的jar包拷贝到lib目录;
第一个程序
既然是研究lucene, 那么就不再写helloword这样的case了,我们这个程序的功能是:
指定一个本地目录,然后对这个目录下的txt文件进行索引,然后根据用户输入的关键词搜索到我们要的文档并打印搜索到的文档的信息。
下面看程序:
view plaincopy to clipboardprint?
package test;
import java.io.*;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopScoreDocCollector;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.util.Version;
public class Test {
// 将要被索引的数据地址, 本例仅局限于txt文件,所以我选择了我曾经下载的spring的src文件来建立索引
public static final String DATA_PATH = "C://doc//spring-framework-2.5.6.SEC01//src//org//springframework//dao";
// 索引文件保存的地址
public static final String INDEX_PATH = "c://index";
// 测试用例
public static void main(String[] args) throws CorruptIndexException,
LockObtainFailedException, IOException, ParseException {
// 创建索引
createIndex(INDEX_PATH, DATA_PATH);
// 搜索关键字"synchronized", 你可以更换关键字试试看.
search("static");
}
/**
* 创建索引
*
* @param indexFolder
* 索引文件存放地址
* @param dataFolder
* 数据文件地址
* @throws CorruptIndexException
* @throws LockObtainFailedException
* @throws IOException
*/
public static void createIndex(String indexFolder, String dataFolder)
throws CorruptIndexException, LockObtainFailedException,
IOException {
// IndexWriter是创建索引的关键 它的构造函数很长,以后会讲解
IndexWriter writer = new IndexWriter(FSDirectory.open(new File(
indexFolder)), new StandardAnalyzer(Version.LUCENE_CURRENT),
true, IndexWriter.MaxFieldLength.LIMITED);
// 根据指定的目录把该目录下所有txt文件索引起来
indexDoc(writer, new File(dataFolder));
// 优化, 可以提高搜索速度。
writer.optimize();
writer.close();
}
/**
* 搜索关键字
*
* @param keyword 关键字
* @throws CorruptIndexException
* @throws IOException
* @throws ParseException
*/
public static void search(String keyword) throws CorruptIndexException,
IOException, ParseException {
// IndexSearcher是实现搜索的关键
IndexSearcher searcher = new IndexSearcher(FSDirectory.open(new File(
INDEX_PATH)), true);
// query代表查询对象
Query query = null;
// 查询解析器, 将查询content字段
QueryParser parser = new QueryParser("content", new StandardAnalyzer(
Version.LUCENE_CURRENT));
query = parser.parse(keyword);
// 搜索结果保存在TopScoreDocCollector.
TopScoreDocCollector c = TopScoreDocCollector.create(100, true);
// 搜索
searcher.search(query, c);
// 得到满足条件的文档总数
System.out.println("总共搜索到 " + c.getTotalHits() + " 个资源。");
// 得到文档集合
ScoreDoc[] docs = c.topDocs(0, c.getTotalHits()).scoreDocs;
// 遍历文档
for (ScoreDoc doc : docs) {
// 需要注意的是:ScoreDoc只记录了文档的id
System.out.println("文档id: " + doc.doc);
System.out.println("相关性评分: " + doc.score);
System.out.println("路径: " + searcher.doc(doc.doc).get("path"));
// 通过IndexSearcher.doc(doc_id)即可得到文档。
Document document = searcher.doc(doc.doc);
// 得到该文档内容content
String content = document.get("content");
System.out.println("内容: " + content);
}
}
/**
* 对指定的目录进行索引
*
* @param writer
* IndexWriter
* @param root
* 指定的目录
*/
private static void indexDoc(IndexWriter writer, File root) {
// 不去索引不能读的文件
if (root.canRead()) {
if (root.isDirectory()) {
File[] files = root.listFiles();
if (files.length != 0) {
for (int i = 0; i < files.length; i++) {
// 递归调用
indexDoc(writer, files[i]);
}
}
} else {
try {
BufferedReader reader = new BufferedReader(new FileReader(
root));
// 文件的文本内容
String content = "";
String line = null;
while ((line = reader.readLine()) != null) {
content += line;
}
reader.close();
// 创建一个lucene document
Document d = new Document();
// 把文件的文本内容添加进来 进行索引,保存
d.add(new Field("content", content, Field.Store.YES,
Field.Index.ANALYZED));
// 同时把path也加入进来,只存储,不索引
d.add(new Field("path", root.getAbsolutePath(),
Field.Store.YES, Field.Index.NOT_ANALYZED));
// 把document写入索引文件
writer.addDocument(d);
System.out.println("add file: " + root.getAbsolutePath());
} catch (FileNotFoundException e) {
System.out.println("file not found, ignored.");
} catch (IOException e) {
}
}
}
}
}
转载:http://blog.csdn.net/sunxing007/archive/2009/11/05/4774240.aspx