???? 在上一篇文章中,我们对Lucene有了大致的了解,Lucene说简单点就是对索引的创建和根据索引进行搜索并返回。接下来我们先学习Lucene环境搭建和索引创建的一些基本类。
???? 在学习Lucene之前,我们先搭建好环境,Eclipse新建一个Maven项目后在pom文件里面加入lucene的jar,完成后,我们就可以开始Lucene的学习之旅了。
<!-- lucene start -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>${lucene.version}</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId> lucene-analyzers-common</artifactId>
<version>${lucene.version}</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>${lucene.version}</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-smartcn</artifactId>
<version>${lucene.version}</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queries</artifactId>
<version>${lucene.version}</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-sandbox</artifactId>
<version>${lucene.version}</version>
</dependency>
<!-- lucene end -->
2.1 IndexWriter
IndexWriter类是Lucene最重要的类,IndexWriter是在索引过程中的中心组件。这个类创建一个新的索引并且添加文档到一个已有的索引中。你可以把IndexWriter 想象成让你可以对索引进行写操作的对象。
初始化一个IndexWriter的方式是:
public void createIndexWriter(){
String index_dir = "E:\\luceneIndex";
IndexWriter indexWriter = new IndexWriter(FSDirectory.open(new File(index_dir)),
new IndexWriterConfig(LUCENE_VERSION,new StandardAnalyzer(LUCENE_VERSION));
}
?
2.2 Directory
Directory 类代表一个Lucene索引的位置,它是一个抽象类,其中有2个实现。
在上面IndexWriter示例中,我们使用一个实际文件系统目录的路径传递给IndexWriter的构造函数来获得Directory的一个实例,并在文件系统的一个目录中创建索引。
2.3 Analyzer
在一个文档被索引之前,首先需要对文档内容进行分词处理,并且而剔除一些冗余的词句(例如:a,the,they等),这部分工作就是由Analyzer来做的。
Analyzer类是一个抽象类,它有很多实现:SimpleAnalyzer,StandardAnalyzer,StopAnalyzer以及WhitespaceAnalyzer等,Analyzer 把分词后的内容交给IndexWriter来建立索引。
2.4 Document
Document文档类似数据库中的一条记录,可以由好几个字段(Field)组成,并且字段可以套用不同的类型。
2.5 Field
Field对象是用来描述一个文档的某个属性的,比如一篇文章的标题和内容可以用两个 Field 对象分别描述。
? 在上文中,我们学习了创建索引的几个重要的类,而索引的完整创建过程,也恰恰是由这些类组成,看下面的测试类。
?
/**
*
* @author tanjie
* 创建时间: 2015-11-4 下午6:12:46
* 描述: 创建简单索引的基本过程
*/
@Test
public void testCreateIndex() {
IndexWriter indexWriter = null;
try {
indexWriter = new IndexWriter(
FSDirectory.open(new File("E:\\luceneIndex")),
new IndexWriterConfig(Version.LUCENE_4_9,
new StandardAnalyzer(Version.LUCENE_4_9)));
Document doc = new Document();
doc.add(new TextField("id", "1", Store.YES));
doc.add(new TextField("id", "2", Store.YES));
indexWriter.addDocument(doc);
indexWriter.commit();
indexWriter.close();
} catch (IOException e) {
e.printStackTrace();
} finally{
if(null != indexWriter){
try {
indexWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
?
?
? 运行上面的代码,会在我们指定的目录,新建一个域为id,值分别为1,2,的索引文件。
4.1 IndexSearcher
IndexSearcher是用来在建立好的索引上进行搜索的,它只能以只读的方式打开一个索引,所以可以有多个IndexSearcher的实例在同一个索引上进行操作。
4.2 Term
Term是 搜索的基本单元,一个Term对象有两个String类型的域组成,字段的名称和字段的值。在搜索时,你可能创建Term对象并和TermQuery同时使用。其中第一个参数代表了要在文档的哪一个Field上进行查找,第二个参数代表了要查询的关键词。
4.3 Query
Query是一个抽象类,这个类的目的是把用户输入的查询字符串封装成Lucene能够识别的Query,它有很多个实现,在后面的章节中我们会单独介绍,这里不加以说明。
4.4 TopDocs
TopDocs是指向匹配的搜索结果的前N个搜索结果,我们可以通过topDocs.scoreDocs来获取一个ScoreDoc[]数组,里面存有我们搜索返回的指定查询条数的结果。
代码片段如下:
//根据query对象查询,最多返回100条结果
TopDocs topDocs = searcher.search(query, 100);
ScoreDoc[] scoreDoc = topDocs.scoreDocs;
for (int i = 0; i < scoreDoc.length; i++) {
Document doc = searcher.doc(scoreDoc[i].doc);
System.out.print("这是第" + (i + 1) + "个检索到的结果");
}
??根据上面的介绍,我们基本可以写出一个简单的搜索方法了,见下面的测试类
?
/**
*
* @author tanjie
* 创建时间: 2015-11-4 下午7:22:54
* 描述: 测试基本的搜索,根据上面刚创建的域为id,值为1,2,的索引进行搜索
*/
@Test
public void testCreateQuery() {
long startTime = new Date().getTime();
IndexSearcher indexSearcher = null;
try {
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_4_9);
indexSearcher = new IndexSearcher(
DirectoryReader.open(FSDirectory.open(new File(
"E:\\luceneIndex"))));
//这里搜索索引的域为id
QueryParser parser = new QueryParser(Version.LUCENE_4_9, "id",
analyzer);
// 将关键字包装成Query对象,搜索对应的值为1的结果
Query query = parser.parse("1");
TopDocs topDocs = indexSearcher.search(query, 100);
System.out.println("一共搜索到:" + topDocs.totalHits + "条记录");
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (int i = 0; i < scoreDocs.length; i++) {
Document document = indexSearcher.doc(topDocs.scoreDocs[i].doc);
System.out.println("搜索结果:" + document.get("id"));
}
long endTime = new Date().getTime();
System.out.println("搜索域为id,值为1的结果耗时:" + (endTime - startTime) + "毫秒");
} catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
}
?
?搜索结果如下:

?
原文:http://090508tanjie.iteye.com/blog/2291752