您的位置:首页 > 其它

Lucene入门一(转)

2008-09-03 22:54 337 查看
说明一下,这一篇文章的用到的lucene,是用2.0版本的,主要在查询的时候2.0版本的lucene与以前的版本有了一些区别.
其实这一些代码都是早几个月写的,自己很懒,所以到今天才写到自己的博客上,高深的文章自己写不了,只能记录下一些简单的记录与点滴,其中的代码算是自娱自乐的,希望高手不要把重构之类的砸下来...

1、在windows系统下的的C盘,建一个名叫s的文件夹,在该文件夹里面随便建三个txt文件,随便起名啦,就叫"1.txt","2.txt"和"3.txt"啦
其中1.txt的内容如下:

Java代码



中华人民共和国

全国人民

2006年
中华人民共和国
全国人民
2006年

而"2.txt"和"3.txt"的内容也可以随便写几写,这里懒写,就复制一个和1.txt文件的内容一样吧

2、下载lucene包,放在classpath路径中
建立索引:

Java代码



package lighter.javaeye.com;

import java.io.BufferedReader;

import java.io.File;

import java.io.FileInputStream;

import java.io.IOException;

import java.io.InputStreamReader;

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.document.Field;

import org.apache.lucene.index.IndexWriter;

/**

* author lighter date 2006-8-7

*/

public class TextFileIndexer {

public static void main(String[] args) throws Exception {

/* 指明要索引文件夹的位置,这里是C盘的S文件夹下 */

File fileDir = new File("c://s");

/* 这里放索引文件的位置 */

File indexDir = new File("c://index");

Analyzer luceneAnalyzer = new StandardAnalyzer();

IndexWriter indexWriter = new IndexWriter(indexDir, luceneAnalyzer,

true);

File[] textFiles = fileDir.listFiles();

long startTime = new Date().getTime();

//增加document到索引去

for (int i = 0; i < textFiles.length; i++) {

if (textFiles[i].isFile()

&& textFiles[i].getName().endsWith(".txt")) {

System.out.println("File " + textFiles[i].getCanonicalPath()

+ "正在被索引....");

String temp = FileReaderAll(textFiles[i].getCanonicalPath(),

"GBK");

System.out.println(temp);

Document document = new Document();

Field FieldPath = new Field("path", textFiles[i].getPath(),

Field.Store.YES, Field.Index.NO);

Field FieldBody = new Field("body", temp, Field.Store.YES,

Field.Index.TOKENIZED,

Field.TermVector.WITH_POSITIONS_OFFSETS);

document.add(FieldPath);

document.add(FieldBody);

indexWriter.addDocument(document);

}

}

//optimize()方法是对索引进行优化

indexWriter.optimize();

indexWriter.close();

//测试一下索引的时间

long endTime = new Date().getTime();

System.out

.println("这花费了"

+ (endTime - startTime)

+ " 毫秒来把文档增加到索引里面去!"

+ fileDir.getPath());

}

public static String FileReaderAll(String FileName, String charset)

throws IOException {

BufferedReader reader = new BufferedReader(new InputStreamReader(

new FileInputStream(FileName), charset));

String line = new String();

String temp = new String();

while ((line = reader.readLine()) != null) {

temp += line;

}

reader.close();

return temp;

}

}
package lighter.javaeye.com;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
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.document.Field;
import org.apache.lucene.index.IndexWriter;

/**
* author lighter date 2006-8-7
*/
public class TextFileIndexer {
public static void main(String[] args) throws Exception {
/* 指明要索引文件夹的位置,这里是C盘的S文件夹下 */
File fileDir = new File("c://s");

/* 这里放索引文件的位置 */
File indexDir = new File("c://index");
Analyzer luceneAnalyzer = new StandardAnalyzer();
IndexWriter indexWriter = new IndexWriter(indexDir, luceneAnalyzer,
true);
File[] textFiles = fileDir.listFiles();
long startTime = new Date().getTime();

//增加document到索引去
for (int i = 0; i < textFiles.length; i++) {
if (textFiles[i].isFile()
&& textFiles[i].getName().endsWith(".txt")) {
System.out.println("File " + textFiles[i].getCanonicalPath()
+ "正在被索引....");
String temp = FileReaderAll(textFiles[i].getCanonicalPath(),
"GBK");
System.out.println(temp);
Document document = new Document();
Field FieldPath = new Field("path", textFiles[i].getPath(),
Field.Store.YES, Field.Index.NO);
Field FieldBody = new Field("body", temp, Field.Store.YES,
Field.Index.TOKENIZED,
Field.TermVector.WITH_POSITIONS_OFFSETS);
document.add(FieldPath);
document.add(FieldBody);
indexWriter.addDocument(document);
}
}
//optimize()方法是对索引进行优化
indexWriter.optimize();
indexWriter.close();

//测试一下索引的时间
long endTime = new Date().getTime();
System.out
.println("这花费了"
+ (endTime - startTime)
+ " 毫秒来把文档增加到索引里面去!"
+ fileDir.getPath());
}

public static String FileReaderAll(String FileName, String charset)
throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(
new FileInputStream(FileName), charset));
String line = new String();
String temp = new String();

while ((line = reader.readLine()) != null) {
temp += line;
}
reader.close();
return temp;
}
}


索引的结果:

Java代码



File C:/s/1.txt正在被索引....

中华人民共和国全国人民2006年

File C:/s/2.txt正在被索引....

中华人民共和国全国人民2006年

File C:/s/3.txt正在被索引....

中华人民共和国全国人民2006年

这花费了297 毫秒来把文档增加到索引里面去!c:/s
File C:/s/1.txt正在被索引....
中华人民共和国全国人民2006年
File C:/s/2.txt正在被索引....
中华人民共和国全国人民2006年
File C:/s/3.txt正在被索引....
中华人民共和国全国人民2006年
这花费了297 毫秒来把文档增加到索引里面去!c:/s


3、建立了索引之后,查询啦....

Java代码



package lighter.javaeye.com;

import java.io.IOException;

import org.apache.lucene.analysis.Analyzer;

import org.apache.lucene.analysis.standard.StandardAnalyzer;

import org.apache.lucene.queryParser.ParseException;

import org.apache.lucene.queryParser.QueryParser;

import org.apache.lucene.search.Hits;

import org.apache.lucene.search.IndexSearcher;

import org.apache.lucene.search.Query;

public class TestQuery {

public static void main(String[] args) throws IOException, ParseException {

Hits hits = null;

String queryString = "中华";

Query query = null;

IndexSearcher searcher = new IndexSearcher("c://index");

Analyzer analyzer = new StandardAnalyzer();

try {

QueryParser qp = new QueryParser("body", analyzer);

query = qp.parse(queryString);

} catch (ParseException e) {

}

if (searcher != null) {

hits = searcher.search(query);

if (hits.length() > 0) {

System.out.println("找到:" + hits.length() + " 个结果!");

}

}

}

}
package lighter.javaeye.com;

import java.io.IOException;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;

public class TestQuery {
public static void main(String[] args) throws IOException, ParseException {
Hits hits = null;
String queryString = "中华";
Query query = null;
IndexSearcher searcher = new IndexSearcher("c://index");

Analyzer analyzer = new StandardAnalyzer();
try {
QueryParser qp = new QueryParser("body", analyzer);
query = qp.parse(queryString);
} catch (ParseException e) {
}
if (searcher != null) {
hits = searcher.search(query);
if (hits.length() > 0) {
System.out.println("找到:" + hits.length() + " 个结果!");
}
}
}

}


其运行结果:

引用
找到:3 个结果!

建立索引

为了对文档进行索引,Lucene 提供了五个基础的类,他们分别是 Document, Field, IndexWriter, Analyzer, Directory。下面我们分别介绍一下这五个类的用途:

Document

Document 是用来描述文档的,这里的文档可以指一个 HTML 页面,一封电子邮件,或者是一个文本文件。一个 Document 对象由多个 Field 对象组成的。可以把一个 Document 对象想象成数据库中的一个记录,而每个 Field 对象就是记录的一个字段。

Field

Field 对象是用来描述一个文档的某个属性的,比如一封电子邮件的标题和内容可以用两个 Field 对象分别描述。

Analyzer

在一个文档被索引之前,首先需要对文档内容进行分词处理,这部分工作就是由 Analyzer 来做的。Analyzer 类是一个抽象类,它有多个实现。针对不同的语言和应用需要选择适合的 Analyzer。Analyzer 把分词后的内容交给 IndexWriter 来建立索引。

IndexWriter

IndexWriter 是 Lucene 用来创建索引的一个核心的类,他的作用是把一个个的 Document 对象加到索引中来。

Directory

这个类代表了 Lucene 的索引的存储的位置,这是一个抽象类,它目前有两个实现,第一个是 FSDirectory,它表示一个存储在文件系统中的索引的位置。第二个是 RAMDirectory,它表示一个存储在内存当中的索引的位置。

我们注意到类 IndexWriter 的构造函数需要三个参数,第一个参数指定了所创建的索引要存放的位置,他可以是一个 File 对象,也可以是一个 FSDirectory 对象或者 RAMDirectory 对象。第二个参数指定了 Analyzer 类的一个实现,也就是指定这个索引是用哪个分词器对文挡内容进行分词。第三个参数是一个布尔型的变量,如果为 true 的话就代表创建一个新的索引,为 false 的话就代表在原来索引的基础上进行操作。接着程序遍历了目录下面的所有文本文档,并为每一个文本文档创建了一个 Document 对象。然后把文本文档的两个属性:路径和内容加入到了两个 Field 对象中,接着在把这两个 Field 对象加入到 Document 对象中,最后把这个文档用 IndexWriter 类的 add 方法加入到索引中去。这样我们便完成了索引的创建。

利用Lucene进行搜索就像建立索引一样也是非常方便的。在上面一部分中,我们已经为一个目录下的文本文档建立好了索引,现在我们就要在这个索引上进行搜索以找到包含某个关键词或短语的文档。Lucene提供了几个基础的类来完成这个过程,它们分别是呢IndexSearcher, Term, Query, TermQuery, Hits. 下面我们分别介绍这几个类的功能。

Query

这是一个抽象类,他有多个实现,比如TermQuery, BooleanQuery, PrefixQuery. 这个类的目的是把用户输入的查询字符串封装成Lucene能够识别的Query。

Term

Term 是搜索的基本单位,一个Term对象有两个String类型的域组成。生成一个Term对象可以有如下一条语句来完成:Term term = new Term(“fieldName”,”queryWord”); 其中第一个参数代表了要在文档的哪一个Field上进行查找,第二个参数代表了要查询的关键词。

TermQuery

TermQuery是抽象类Query的一个子类,它同时也是Lucene支持的最为基本的一个查询类。生成一个TermQuery对象由如下语句完成: TermQuery termQuery = new TermQuery(new Term(“fieldName”,”queryWord”)); 它的构造函数只接受一个参数,那就是一个Term对象。

IndexSearcher

IndexSearcher是用来在建立好的索引上进行搜索的。它只能以只读的方式打开一个索引,所以可以有多个IndexSearcher的实例在一个索引上进行操作。

Hits

Hits是用来保存搜索的结果的。

介绍完这些搜索所必须的类之后,我们就开始在之前所建立的索引上进行搜索了,清单2给出了完成搜索功能所需要的代码。

类IndexSearcher的构造函数接受一个类型为Directory的对象,Directory是一个抽象类,它目前有两个子类:FSDirctory和RAMDirectory. 我们的程序中传入了一个FSDirctory对象作为其参数,代表了一个存储在磁盘上的索引的位置。构造函数执行完成后,代表了这个 IndexSearcher以只读的方式打开了一个索引。然后我们程序构造了一个Term对象,通过这个Term对象,我们指定了要在文档的内容中搜索包含关键词”lucene”的文档。接着利用这个Term对象构造出TermQuery对象并把这个TermQuery对象传入到 IndexSearcher的search方法中进行查询,返回的结果保存在Hits对象中。最后我们用了一个循环语句把搜索到的文档的路径都打印了出来。好了,我们的搜索应用程序已经开发完毕,怎么样,利用Lucene开发搜索应用程序是不是很简单。

http://www.ibm.com/developerworks/cn/java/j-lo-lucene1/#N1004B
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: