???? 在上一篇文章中,我们对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