TutorialsPoint Lucene 教程

来源：易百教程

Lucene教程

Lucene是简单而功能强大的基于Java的搜索库。它可以用于任何应用程序来搜索功能。 Lucene是开源项目。它是可扩展的，高性能的库用于索引和搜索几乎任何类型的文本。 Lucene库提供了所需的任何搜索应用程序的核心业务。索引和搜索。

搜索应用程序的工作原理

任何搜索应用程序执行一些或全部下列操作。

步骤 | 标题 | 描述
1 | 获取原始内容 | 任何搜索应用程序的第一个步骤是收集在其上的搜索是要进行的目标内容。
2 | 构建文档 | 下一步是建立从原始内容的搜索应用程序可以理解和容易理解的文件。
3 | 分析文档 | 在索引过程启动，该文件是要分析作为其文本部分是一个候选索引。这个过程被称为分析文档。
4 | 索引文件 | 一旦文档被构建和分析，下一步是将索引它们使得该文件可被检索

Lucene环境设置 - Lucene教程

环境设置

本教程将指导如何准备一个开发环境，开始与Spring框架工作。本教程还将教如何安装JDK，Tomcat和Eclipse在机器上在设置Spring框架之前：

第1步 - 安装Java开发工具包(JDK)：

可以从OracleJava网站上找到最新版本的SDK：Java SE下载。发现有说明在下载的文件中说明处理安装JDK，按照说明安装和配置设置的指示。最后，设置PATH和JAVA_HOME环境变量指的是分别包含java和javac，通常java_install_dir/bin和java_install_dir目录。

如果运行的是Windows，并安装了JDK在 C:jdk1.6.0_15，就必须执行以下C: autoexec.bat。

set PATH=C:jdk1.6.0_15in;%PATH%
set JAVA_HOME=C:jdk1.6.0_15

另外如果在Windows NT/2000/XP中，也可以在“我的电脑”，选择“属性”，然后“高级”，然后环境变量单击鼠标右键。更新PATH的值，然后按OK按钮。

在Unix（Solaris和Linux等），如果SDK安装在/usr/local/jdk1.6.0_15并且使用的是C shell，把下列内容放入.cshrc文件。

setenv PATH /usr/local/jdk1.6.0_15/bin:$PATH
setenv JAVA_HOME /usr/local/jdk1.6.0_15

另外，如果使用的集成开发环境（IDE）像Borland公司的JBuilder，Eclipse或IntelliJ IDEA或Sun ONE Studio，那么编译并运行一个简单的程序，以确认该IDE知道安装Java，否则需要为IDE做适当的设置。

第2步 - 安装Eclipse IDE

在本教程中的所有示例使用Eclipse IDE。所以建议你应该在计算机上安装最新版本的 Eclipse。

要安装Eclipse IDE，请从 http://www.eclipse.org/downloads/ 上下载最新的 Eclipse 可执行文件并安装，解压缩二进制分发到一个方便的位置。例如，在C： Eclipse在Windows上，或在Linux/Unix的 /usr/local/eclipse，最后设置PATH变量恰当即可。

Eclipse可以通过在Windows计算机上执行以下命令来启动，或者可以简单地双击 eclipse.exe

 %C:eclipseeclipse.exe

Eclipse可以通过执行在Unix（Solaris和Linux等）机器下面的命令来启动：

$/usr/local/eclipse/eclipse

成功启动后，如果一切正常那么就应该显示如下结果：

第3步 - 安装Lucene框架库

现在，如果一切正常，那么就可以继续设的Lucene框架。以下是简单的步骤下载并在机器上安装Lucene框架。

选择是否要在Windows或UNIX上安装Lucene，然后进行下一个步骤下载 .zip 文件适用于Windows，以及 .tz 文件适用在 Unix 中。

从下载合适版本的Lucene的框架二进制文件 http://archive.apache.org/dist/lucene/java/.

在写这篇教程的时候，下载lucene-3.6.2.zip在Windows机器上，当解压缩下载的文件，它会给出里面的目录结构在 C:lucene-3.6.2 如下。

会发现所有的Lucene库在C:lucene-3.6.2 目录。确保在这个目录上设置CLASSPATH变量正确，否则会在运行应用程序时出现问题。如果使用的是 Eclipse 则不需要设置 CLASSPATH，因为所有的设置已通过Eclipse进行。

最后一步完成后，就可以开始Lucene的第一个例子，在下一章中将看到。

Lucene第一个应用程序 - Lucene教程

让我们使用Lucene框架做实际编程。在开始使用Lucene框架编写第一个例子之前，必须确保已经安装Lucene的环境正常。也假设有一点点的工作和Eclipse IDE的知识。

因此，开始写一个简单的搜索应用程序将打印找到搜索结果数量。我们也看到在这个过程中创建的索引列表。

第1步 - 创建Java项目：

第一步是使用Eclipse IDE创建一个简单的Java项目。按照选项 File -> New -> Project 最后选择 Java Project 从向导列表向导。现在，项目命名为 LuceneFirstApplication 使用向导窗口，如下所示：

一旦项目成功创建，将有以下内容在 Project Explorer:

第2步 - 添加必需的库：

作为第二步，我们添加Lucene核心框架库在项目中。要做到这一点，右键单击项目名称LuceneFirstApplication然后按照上下文菜单中提供以下选项：Build Path -> Configure Build Path，显示了Java构建路径如下窗口：

现在，使用添加在库选项卡中提供外部JAR按钮，添加Lucene安装目录下的核心JAR：

lucene-core-3.6.2

第3步 - 创建源文件：

现在，让我们 LuceneFirstApplication 项目下创建实际的源文件。首先，我们需要创建一个名为 com.yiibai.lucene 包。要做到这一点，右键单击 src 在包资源管理部分，并按照选项：New -> Package.

下一步，我们将创建 LuceneTester.java 和 其他Java类在 com.yiibai.lucene 包下。

LuceneConstants.java

这个类是用来提供跨示例应用程序中使用的各种常量。

package com.yiibai.lucene;

public class LuceneConstants {
   public static final String CONTENTS="contents";
   public static final String FILE_NAME="filename";
   public static final String FILE_PATH="filepath";
   public static final int MAX_SEARCH = 10;
}

TextFileFilter.java

此类用于为 .txt 文件过滤器

package com.yiibai.lucene;

import java.io.File;
import java.io.FileFilter;

public class TextFileFilter implements FileFilter {

   @Override
   public boolean accept(File pathname) {
      return pathname.getName().toLowerCase().endsWith(".txt");
   }
}

Indexer.java

这个类是用于索引的原始数据，这样我们就可以使用Lucene库，使其可搜索。

package com.yiibai.lucene;

import java.io.File;
import java.io.FileFilter;
import java.io.FileReader;
import java.io.IOException;

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.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

public class Indexer {

   private IndexWriter writer;

   public Indexer(String indexDirectoryPath) throws IOException{
      //this directory will contain the indexes
      Directory indexDirectory =
         FSDirectory.open(new File(indexDirectoryPath));

      //create the indexer
      writer = new IndexWriter(indexDirectory,
         new StandardAnalyzer(Version.LUCENE_36),true,
         IndexWriter.MaxFieldLength.UNLIMITED);
   }

   public void close() throws CorruptIndexException, IOException{
      writer.close();
   }

   private Document getDocument(File file) throws IOException{
      Document document = new Document();

      //index file contents
      Field contentField = new Field(LuceneConstants.CONTENTS,
         new FileReader(file));
      //index file name
      Field fileNameField = new Field(LuceneConstants.FILE_NAME,
         file.getName(),
         Field.Store.YES,Field.Index.NOT_ANALYZED);
      //index file path
      Field filePathField = new Field(LuceneConstants.FILE_PATH,
         file.getCanonicalPath(),
         Field.Store.YES,Field.Index.NOT_ANALYZED);

      document.add(contentField);
      document.add(fileNameField);
      document.add(filePathField);

      return document;
   }

   private void indexFile(File file) throws IOException{
      System.out.println("Indexing "+file.getCanonicalPath());
      Document document = getDocument(file);
      writer.addDocument(document);
   }

   public int createIndex(String dataDirPath, FileFilter filter)
      throws IOException{
      //get all files in the data directory
      File[] files = new File(dataDirPath).listFiles();

      for (File file : files) {
         if(!file.isDirectory()
            && !file.isHidden()
            && file.exists()
            && file.canRead()
            && filter.accept(file)
         ){
            indexFile(file);
         }
      }
      return writer.numDocs();
   }
}

Searcher.java

这个类是用来搜索索引所创建的索引搜索请求的内容。

package com.yiibai.lucene;

import java.io.File;
import java.io.IOException;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
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.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

public class Searcher {

   IndexSearcher indexSearcher;
   QueryParser queryParser;
   Query query;

   public Searcher(String indexDirectoryPath)
      throws IOException{
      Directory indexDirectory =
         FSDirectory.open(new File(indexDirectoryPath));
      indexSearcher = new IndexSearcher(indexDirectory);
      queryParser = new QueryParser(Version.LUCENE_36,
         LuceneConstants.CONTENTS,
         new StandardAnalyzer(Version.LUCENE_36));
   }

   public TopDocs search( String searchQuery)
      throws IOException, ParseException{
      query = queryParser.parse(searchQuery);
      return indexSearcher.search(query, LuceneConstants.MAX_SEARCH);
   }

   public Document getDocument(ScoreDoc scoreDoc)
      throws CorruptIndexException, IOException{
      return indexSearcher.doc(scoreDoc.doc);
   }

   public void close() throws IOException{
      indexSearcher.close();
   }
}

LuceneTester.java

这个类是用来测试 Lucene 库的索引和搜索功能。

package com.yiibai.lucene;

import java.io.IOException;

import org.apache.lucene.document.Document;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;

public class LuceneTester {

   String indexDir = "E:\Lucene\Index";
   String dataDir = "E:\Lucene\Data";
   Indexer indexer;
   Searcher searcher;

   public static void main(String[] args) {
      LuceneTester tester;
      try {
         tester = new LuceneTester();
         tester.createIndex();
         tester.search("Mohan");
      } catch (IOException e) {
         e.printStackTrace();
      } catch (ParseException e) {
         e.printStackTrace();
      }
   }

   private void createIndex() throws IOException{
      indexer = new Indexer(indexDir);
      int numIndexed;
      long startTime = System.currentTimeMillis();
      numIndexed = indexer.createIndex(dataDir, new TextFileFilter());
      long endTime = System.currentTimeMillis();
      indexer.close();
      System.out.println(numIndexed+" File indexed, time taken: "
         +(endTime-startTime)+" ms");
   }

   private void search(String searchQuery) throws IOException, ParseException{
      searcher = new Searcher(indexDir);
      long startTime = System.currentTimeMillis();
      TopDocs hits = searcher.search(searchQuery);
      long endTime = System.currentTimeMillis();

      System.out.println(hits.totalHits +
         " documents found. Time :" + (endTime - startTime));
      for(ScoreDoc scoreDoc : hits.scoreDocs) {
         Document doc = searcher.getDocument(scoreDoc);
            System.out.println("File: "
            + doc.get(LuceneConstants.FILE_PATH));
      }
      searcher.close();
   }
}

第4步- 创建数据和索引目录

把 record1.txt 任命为 record10.txt 包含简单的名称以及学生的其他数据信息，并把它们放在目录：E:LuceneData 并测试数据。索引目录路径应创建在 E:LuceneIndex。运行此程序后，就可以看到该文件夹中创建的索引文件的列表。

第5步 - 运行程序：

一旦完成创建源和原始数据，数据目录和索引目录，下一步是编译和运行程序。要做到这一点，请LuceneTester.Java文件的活动选项卡中使用EclipseIDE可无论是运行选项，或使用Ctrl+ F11来编译和运行应用程序LuceneTester。如果一切正常您的应用程序，这将打印在 Eclipse IDE 控制台以下消息：

Indexing E:LuceneData
ecord1.txt
Indexing E:LuceneData
ecord10.txt
Indexing E:LuceneData
ecord2.txt
Indexing E:LuceneData
ecord3.txt
Indexing E:LuceneData
ecord4.txt
Indexing E:LuceneData
ecord5.txt
Indexing E:LuceneData
ecord6.txt
Indexing E:LuceneData
ecord7.txt
Indexing E:LuceneData
ecord8.txt
Indexing E:LuceneData
ecord9.txt
10 File indexed, time taken: 109 ms
1 documents found. Time :0
File: E:LuceneData
ecord4.txt

一旦已经成功地运行程序，将有以下的索引目录中的内容：

Lucene索引类 - Lucene教程

索引过程是由Lucene所提供的核心功能之一。下图说明了索引过程和使用的类。IndexWriter 是索引过程中最重要的和核心组件。

我们添加包含字段的 IndexWriter 分析使用 Analyzer 文件，然后创建/根据需要打开/编辑索引和存储/在目录更新。IndexWriter用于更新或创建索引。它不是用来读取索引。

Indexing类 :

以下是常用索引进程类的列表。

Sr. No. | 类及描述
1 | IndexWriter 此类充当创造/在索引过程中更新指标的核心组成部分
2 | Directory 此类表示索引的存储位置
3 | Analyzer Analyzer类负责分析一个文件，并从将被索引的文本获取令牌/字。不加分析完成后，IndexWriter不能创建索引。
4 | Document Document代表一个虚拟文档与字段，其中字段是可包含在物理文档的内容，元数据等对象。Analyzer只能理解文档。
5 | Field Field是最低单元或索引过程的起点。它代表其中一个键被用于识别要被索引的值的键值对关系。用于表示一个文件内容的字段将具有键为“内容”，值可以包含文本或文档的数字内容的部分或全部。 Lucene能索引仅文本或仅数字内容。

Lucene Searching类 - Lucene教程

在搜索过程是由Lucene所提供的核心功能之一。它的流程是相似于索引过程。 Lucene基本搜索可以使用下列类也可称为基础类的所有搜索相关的操作进行。

Searching 类:

以下是常用的类中搜索处理的列表。

Sr. No. | 类和说明
1 | IndexSearcher 这个类充当读取/搜索索引的过程后创建索引的核心组成部分。它需要目录实例指向包含索引的位置
2 | Term 这个类是搜索的最低单位。它是在索引过程中类似字段 Field
3 | Query Query是一个抽象类，包含各种实用方法，所有类型查询的父在Lucene的搜索过程中使用
4 | TermQuery TermQuery是最常用的查询对象，并且是许多复杂的查询lucene可利用的基础
5 | TopDocs TopDocs指向相匹配的搜索条件的前N个搜索结果。它是指针的简单容器指向它们的搜索结果输出的文档。

Lucene索引过程 - Lucene教程

索引过程是Lucene提供的核心功能之一。下图说明了索引过程和使用的类。IndexWriter是索引过程中最重要的和核心组件。

添加文档包含字段IndexWriter，该分析用分析仪分析文件，然后创建/根据需要并在目录存储/更新/打开/编辑索引。IndexWriter用于更新或创建索引。它不是用来读取索引。

现在，展示一个循序渐进的过程，以获得在索引过程的理解，使用一个基本的例子。

创建一个文档

创建一个方法来获取从文本文件中获得 Lucene 的文档。

创建各种类型的是含有键作为名称和值作为内容被编入索引键值对字段。

设置字段中进行分析或不设置。在我们的实例中，只有内容被分析，因为它可能包含数据，诸如 a, am, are, an，它不要求在搜索操作等等。

新创建的字段添加到文档对象并返回给调用者的方法。

private Document getDocument(File file) throws IOException{
   Document document = new Document();

   //index file contents
   Field contentField = new Field(LuceneConstants.CONTENTS,
      new FileReader(file));
   //index file name
   Field fileNameField = new Field(LuceneConstants.FILE_NAME,
      file.getName(),
      Field.Store.YES,Field.Index.NOT_ANALYZED);
   //index file path
   Field filePathField = new Field(LuceneConstants.FILE_PATH,
      file.getCanonicalPath(),
      Field.Store.YES,Field.Index.NOT_ANALYZED);

   document.add(contentField);
   document.add(fileNameField);
   document.add(filePathField);

   return document;
}

创建IndexWriter

IndexWriter 类作为它创建/在索引过程中更新指标的核心组成部分

创建一个 IndexWriter 对象

创建其应指向位置，其中索引是存储一个lucene的目录

初始化索引目录，有标准的分析版本信息和其他所需/可选参数创建 IndexWriter 对象

private IndexWriter writer;

public Indexer(String indexDirectoryPath) throws IOException{
   //this directory will contain the indexes
   Directory indexDirectory =
      FSDirectory.open(new File(indexDirectoryPath));
   //create the indexer
   writer = new IndexWriter(indexDirectory,
      new StandardAnalyzer(Version.LUCENE_36),true,
      IndexWriter.MaxFieldLength.UNLIMITED);
}

开始索引过程

private void indexFile(File file) throws IOException{
   System.out.println("Indexing "+file.getCanonicalPath());
   Document document = getDocument(file);
   writer.addDocument(document);
}

应用程序示例

让我们创建一个测试 Lucene 应用程序来测试索引过程。

步骤 | 描述
1 | 在 packagecom.yiibai.lucene 包下创建一个名称 LuceneFirstApplication 项目用于解释 Lucene - First Application chapter, 也可以使用 Lucene 的创建项目 - 在 First Application 章这样本章理解索引过程。
2 | 创建LuceneConstants.java，TextFileFilter.java和 Indexer.java，其它的文件保存不变。
3 | 创建LuceneTester.java如下所述
4 | 清理和构建应用程序，以确保业务逻辑按要求

LuceneConstants.java

这个类是用来提供跨示例应用程序中使用的各种常量

package com.yiibai.lucene;

public class LuceneConstants {
   public static final String CONTENTS="contents";
   public static final String FILE_NAME="filename";
   public static final String FILE_PATH="filepath";
   public static final int MAX_SEARCH = 10;
}

TextFileFilter.java

此类用于为 .txt 文件过滤器

package com.yiibai.lucene;

import java.io.File;
import java.io.FileFilter;

public class TextFileFilter implements FileFilter {

   @Override
   public boolean accept(File pathname) {
      return pathname.getName().toLowerCase().endsWith(".txt");
   }
}

Indexer.java

这个类是用于索引的原始数据，这样就可以使用Lucene库，使其可搜索。

package com.yiibai.lucene;

import java.io.File;
import java.io.FileFilter;
import java.io.FileReader;
import java.io.IOException;

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.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

public class Indexer {

   private IndexWriter writer;

   public Indexer(String indexDirectoryPath) throws IOException{
      //this directory will contain the indexes
      Directory indexDirectory =
         FSDirectory.open(new File(indexDirectoryPath));

      //create the indexer
      writer = new IndexWriter(indexDirectory,
         new StandardAnalyzer(Version.LUCENE_36),true,
         IndexWriter.MaxFieldLength.UNLIMITED);
   }

   public void close() throws CorruptIndexException, IOException{
      writer.close();
   }

   private Document getDocument(File file) throws IOException{
      Document document = new Document();

      //index file contents
      Field contentField = new Field(LuceneConstants.CONTENTS,
         new FileReader(file));
      //index file name
      Field fileNameField = new Field(LuceneConstants.FILE_NAME,
         file.getName(),
         Field.Store.YES,Field.Index.NOT_ANALYZED);
      //index file path
      Field filePathField = new Field(LuceneConstants.FILE_PATH,
         file.getCanonicalPath(),
         Field.Store.YES,Field.Index.NOT_ANALYZED);

      document.add(contentField);
      document.add(fileNameField);
      document.add(filePathField);

      return document;
   }

   private void indexFile(File file) throws IOException{
      System.out.println("Indexing "+file.getCanonicalPath());
      Document document = getDocument(file);
      writer.addDocument(document);
   }

   public int createIndex(String dataDirPath, FileFilter filter)
      throws IOException{
      //get all files in the data directory
      File[] files = new File(dataDirPath).listFiles();

      for (File file : files) {
         if(!file.isDirectory()
            && !file.isHidden()
            && file.exists()
            && file.canRead()
            && filter.accept(file)
         ){
            indexFile(file);
         }
      }
      return writer.numDocs();
   }
}

LuceneTester.java

这个类是用来测试 Lucene 库的索引能力。

package com.yiibai.lucene;

import java.io.IOException;

public class LuceneTester {

   String indexDir = "E:\Lucene\Index";
   String dataDir = "E:\Lucene\Data";
   Indexer indexer;

   public static void main(String[] args) {
      LuceneTester tester;
      try {
         tester = new LuceneTester();
         tester.createIndex();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }

   private void createIndex() throws IOException{
      indexer = new Indexer(indexDir);
      int numIndexed;
      long startTime = System.currentTimeMillis();
      numIndexed = indexer.createIndex(dataDir, new TextFileFilter());
      long endTime = System.currentTimeMillis();
      indexer.close();
      System.out.println(numIndexed+" File indexed, time taken: "
         +(endTime-startTime)+" ms");
   }
}

数据和索引目录的创建

从 record1.txt 命名文件 record10.txt 包含简单的名称以及学生的其他细节，并把它们放在目录 E:LuceneData. 索引目录路径应创建为 E:LuceneIndex. 运行此程序后，就可以看到该文件夹中创建的索引文件的列表。

运行程序：

一旦使用创建源，创造了原始数据，数据目录和索引目录来完成，准备好这一步然后编译和运行程序。要做到这一点，保存LuceneTester.Java文件选项卡中使用Eclipse IDE 运行 Run 选项，或使用Ctrl+ F11来编译和运行应用程序LuceneTester。如果应用程序一切正常，这将打印在Eclipse IDE的控制台以下消息：

Indexing E:LuceneData
ecord1.txt
Indexing E:LuceneData
ecord10.txt
Indexing E:LuceneData
ecord2.txt
Indexing E:LuceneData
ecord3.txt
Indexing E:LuceneData
ecord4.txt
Indexing E:LuceneData
ecord5.txt
Indexing E:LuceneData
ecord6.txt
Indexing E:LuceneData
ecord7.txt
Indexing E:LuceneData
ecord8.txt
Indexing E:LuceneData
ecord9.txt
10 File indexed, time taken: 109 ms

一旦成功地运行程序，将有以下的索引目录中的内容：

Lucene索引操作 - Lucene教程

在本章中，我们将讨论索引的四个主要操作。这些操作是在不同的时间和有用用于整个软件搜索应用程序。

索引操作：

以下是常用的操作过程中索引进程列表。

Sr. No. | 操作说明：
1 | Add Document 此操作在索引进程列表的初始阶段用于在新的可用内容创建索引
2 | Update Document 此操作用于更新索引以反映变化的更新的内容。它类似于重新创建索引
3 | Delete Document 此操作用于更新的索引以排除它们不需要被索引的文档/搜索
4 | Field Options 字段选项指定的方式或控制的方式，一个字段的内容进行搜索

Lucene搜索操作 - Lucene教程

搜索过程是由Lucene所提供的核心功能之一。下图说明了搜索过程和使用的类。 IndexSearcher是搜索过程中最重要的和核心组件。

我们首先创建目录包含索引，然后将它传递给IndexSearcher，它使用IndexReader打开目录。然后，创建一个期限查询，使搜索usingIndexSearcher通过将查询到的搜索。 IndexSearcher返回TopDocs对象包含搜索信息连同它是搜索操作的结果的文档的文档ID(多个)。

现在，我们将展示一个循序渐进的过程，以获得在索引过程的理解，使用一个基本的例子。

创建QueryParser

QueryParser类解析用户输入，并输入到 Lucene 理解的格式的查询。

创建QueryParser的对象。

初始化一个在此查询运行有标准的分析版本信息和索引的名字创建QueryParser对象。

QueryParser queryParser;

public Searcher(String indexDirectoryPath) throws IOException{

   queryParser = new QueryParser(Version.LUCENE_36,
      LuceneConstants.CONTENTS,
         new StandardAnalyzer(Version.LUCENE_36));
}

创建IndexSearcher

IndexSearcher类作为它在索引过程中创建搜索索引的核心组成部分。

创建IndexSearcher对象。

创建其应指向位置，其中索引是存储一个 lucene 的目录。

初始化索引目录中创建 IndexSearcher 的对象

IndexSearcher indexSearcher;

public Searcher(String indexDirectoryPath) throws IOException{
   Directory indexDirectory =
      FSDirectory.open(new File(indexDirectoryPath));
   indexSearcher = new IndexSearcher(indexDirectory);
}

搜索

要开始搜索，通过 QueryParser 解析搜索表达式创建一个查询对象。

通过调用IndexSearcher.search()方法搜索。

Query query;

public TopDocs search( String searchQuery) throws IOException, ParseException{
   query = queryParser.parse(searchQuery);
   return indexSearcher.search(query, LuceneConstants.MAX_SEARCH);
}

获取文件

public Document getDocument(ScoreDoc scoreDoc)
   throws CorruptIndexException, IOException{
   return indexSearcher.doc(scoreDoc.doc);
}

关闭IndexSearcher

public void close() throws IOException{
   indexSearcher.close();
}

应用程序示例

让我们创建一个测试Lucene的应用程序来测试搜索过程。

步骤 | 描述
1 | 创建下名称为LuceneFirstApplication的一个项目作为解释Lucene的应用在包packagecom.yiibai.lucene下，在第一个应用程序的篇章。也可以使用Lucene创建的项目理解搜索过程。
2 | 创建LuceneConstants.java，TextFileFilter.java和Searcher.java 用于 Lucene解释- 在第一应用章节。其它文件保持不变。
3 | 创建LuceneTester.java如下所述。
4 | 清理和构建应用程序，以确保业务逻辑按要求工作。

LuceneConstants.java

这个类是用来提供可应用于示例应用程序中使用的各种常量。

package com.yiibai.lucene;

public class LuceneConstants {
   public static final String CONTENTS="contents";
   public static final String FILE_NAME="filename";
   public static final String FILE_PATH="filepath";
   public static final int MAX_SEARCH = 10;
}

TextFileFilter.java

此类用于 .txt文件过滤器。

package com.yiibai.lucene;

import java.io.File;
import java.io.FileFilter;

public class TextFileFilter implements FileFilter {

   @Override
   public boolean accept(File pathname) {
      return pathname.getName().toLowerCase().endsWith(".txt");
   }
}

Searcher.java

这个类用来读取就使用Lucene库的原始数据，并搜索数据的索引。

package com.yiibai.lucene;

import java.io.File;
import java.io.IOException;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
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.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

public class Searcher {

   IndexSearcher indexSearcher;
   QueryParser queryParser;
   Query query;

   public Searcher(String indexDirectoryPath) throws IOException{
      Directory indexDirectory =
         FSDirectory.open(new File(indexDirectoryPath));
      indexSearcher = new IndexSearcher(indexDirectory);
      queryParser = new QueryParser(Version.LUCENE_36,
         LuceneConstants.CONTENTS,
         new StandardAnalyzer(Version.LUCENE_36));
   }

   public TopDocs search( String searchQuery)
      throws IOException, ParseException{
      query = queryParser.parse(searchQuery);
      return indexSearcher.search(query, LuceneConstants.MAX_SEARCH);
   }

   public Document getDocument(ScoreDoc scoreDoc)
      throws CorruptIndexException, IOException{
     return indexSearcher.doc(scoreDoc.doc);
   }

   public void close() throws IOException{
      indexSearcher.close();
   }
}

LuceneTester.java

这个类是用来测试 Lucene 库的搜索能力。

package com.yiibai.lucene;

import java.io.IOException;

import org.apache.lucene.document.Document;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;

public class LuceneTester {

   String indexDir = "E:\Lucene\Index";
   String dataDir = "E:\Lucene\Data";
   Searcher searcher;

   public static void main(String[] args) {
      LuceneTester tester;
      try {
         tester = new LuceneTester();
         tester.search("Mohan");
      } catch (IOException e) {
         e.printStackTrace();
      } catch (ParseException e) {
         e.printStackTrace();
      }
   }

   private void search(String searchQuery) throws IOException, ParseException{
      searcher = new Searcher(indexDir);
      long startTime = System.currentTimeMillis();
      TopDocs hits = searcher.search(searchQuery);
      long endTime = System.currentTimeMillis();

      System.out.println(hits.totalHits +
         " documents found. Time :" + (endTime - startTime) +" ms");
      for(ScoreDoc scoreDoc : hits.scoreDocs) {
         Document doc = searcher.getDocument(scoreDoc);
         System.out.println("File: "+ doc.get(LuceneConstants.FILE_PATH));
      }
      searcher.close();
   }
}

数据和索引目录的创建

从record1.txt到record10.txt的文件中包含简单的名称以及学生的其他细节，并把它们放在目录E:LuceneData。这是测试数据。索引目录路径应创建为E:LuceneIndex。期间，运行 Lucene索引程序后- 索引过程中，可以看到该文件夹中创建的索引文件的列表。

运行程序：

一旦创建源，创造了原始数据，数据目录，索引目录和索引完成后，已经准备好这一步是编译和运行程序。要做到这一点，请LuceneTester.Java文件选项卡中使用Eclipse IDE可使用Run选项，或使用Ctrl+ F11来编译和运行应用程序LuceneTester。如果您的应用程序一切正常，这将在Eclipse IDE的控制台打印以下消息：

1 documents found. Time :29 ms
File: E:LuceneData
ecord4.txt

Lucene查询编程 - Lucene教程

正如我们已经看到在前面的章节中的Lucene- 搜索操作，Lucene使用IndexSearcher进行搜索，并使用由QueryParser输入创建的查询对象。在本章中，我们将讨论不同类型的查询对象和方法以编程方式来创建它们。创建不同类型的查询对象的给出了要进行搜索类型的控制。

考虑高级搜索的情况下，许多应用程序，用户给出了多个选项来限制搜索结果中提供。通过查询程序，我们一样可以很轻松的实现。

以下是查询类型，我们将在适当的时候讨论的列表。

Sr. No. | 类和说明
1 | TermQuery 此类充当创造/在索引处理更新指标的核心组成部分。
2 | TermRangeQuery TermRangeQuery是在使用的范围内的文本的词条都被搜索。
3 | PrefixQuery PrefixQuery用于匹配其索引开始以指定的字符串的文档。
4 | BooleanQuery BooleanQuery用于搜索的是使用AND，OR或NOT运算符多个查询结果的文件。
5 | PhraseQuery 词组查询用于搜索包含词条的特定序列的文档。
6 | WildCardQuery WildcardQuery用于搜索使用类似 '*' 的字符序列的通配符的文件，"?" 匹配单个字符。
7 | FuzzyQuery FuzzyQuery用于搜索使用模糊实现，它是一种基于编辑距离算法的近似搜索文件。
8 | MatchAllDocsQuery MatchAllDocsQuery作为顾名思义匹配的所有文件。

Lucene分析 - Lucene教程

正如我们已经看到在前一章的Lucene索引过程，Lucene使用IndexWriterwhich分析用分析仪文件，然后根据需要创建/打开/编辑索引。在本章中，我们将讨论不同类型的分析对象，哪些是在分析过程中使用的相关对象。了解分析过程中，分析仪如何工作，会给Lucene索引文件很大的启示。

以下是我们将在适当的时候讨论对象的列表。

Sr. No. | 类和说明
1 | Token 令牌表示(起始偏移量，结束偏移，令牌类型和位置增量位置，)在像它的元数据相关的详细信息的文档中的文本或字。
2 | TokenStream TokenStream是分析过程中的一个输出，它包括串联的令牌。它是一个抽象类。
3 | Analyzer 这是对每个类型分析器的抽象基类。
4 | WhitespaceAnalyzer 该分析仪analyzer分割的基础的空白文档中的文本。
5 | SimpleAnalyzer 此分析器分割在基于非字母字符的文档的文本，然后小写它们。
6 | StopAnalyzer 该分析仪的工作原理类似于SimpleAnalyzer并删除常用词像 'a','an','the'等等。
7 | StandardAnalyzer 这是最复杂的分析，并能处理姓名，电子邮件地址等，它小写每个标记，并删除常用词和标点符号(如有)。

Lucene排序 - Lucene教程

在本章中，我们将研究的排序顺序默认情况下，在给出的Lucene搜索结果或可根据需要进行操作。

按相关性排序

这是使用Lucene的默认排序方式。 Lucene通过在顶部的最相关的命中提供的结果。

private void sortUsingRelevance(String searchQuery)
   throws IOException, ParseException{
   searcher = new Searcher(indexDir);
   long startTime = System.currentTimeMillis();
   //create a term to search file name
   Term term = new Term(LuceneConstants.FILE_NAME, searchQuery);
   //create the term query object
   Query query = new FuzzyQuery(term);
   searcher.setDefaultFieldSortScoring(true, false);
   //do the search
   TopDocs hits = searcher.search(query,Sort.RELEVANCE);
   long endTime = System.currentTimeMillis();

   System.out.println(hits.totalHits +
      " documents found. Time :" + (endTime - startTime) + "ms");
   for(ScoreDoc scoreDoc : hits.scoreDocs) {
      Document doc = searcher.getDocument(scoreDoc);
      System.out.print("Score: "+ scoreDoc.score + " ");
      System.out.println("File: "+ doc.get(LuceneConstants.FILE_PATH));
   }
   searcher.close();
}

选择IndexOrder排序方式

这被分拣使用lucene模式，其中索引第一文档示出第一搜索结果中。

private void sortUsingIndex(String searchQuery)
   throws IOException, ParseException{
   searcher = new Searcher(indexDir);
   long startTime = System.currentTimeMillis();
   //create a term to search file name
   Term term = new Term(LuceneConstants.FILE_NAME, searchQuery);
   //create the term query object
   Query query = new FuzzyQuery(term);
   searcher.setDefaultFieldSortScoring(true, false);
   //do the search
   TopDocs hits = searcher.search(query,Sort.INDEXORDER);
   long endTime = System.currentTimeMillis();

   System.out.println(hits.totalHits +
      " documents found. Time :" + (endTime - startTime) + "ms");
   for(ScoreDoc scoreDoc : hits.scoreDocs) {
      Document doc = searcher.getDocument(scoreDoc);
      System.out.print("Score: "+ scoreDoc.score + " ");
      System.out.println("File: "+ doc.get(LuceneConstants.FILE_PATH));
   }
   searcher.close();
}

应用程序示例...

让我们创建一个测试Lucene的应用程序来测试分选过程。

步骤 | 描述
1 | 创建下名称为LuceneFirstApplication的一个项目作为解释Lucene的应用在包packagecom.yiibai.lucene下，在第一个应用程序的篇章。也可以使用Lucene创建的项目理解搜索过程。
2 | 创建LuceneConstants.java和Searcher.java作为Lucene的解释- 第一应用程序一章。保持其它文件不变。
3 | 创建LuceneTester.java如下所述。
4 | 清理和构建应用程序，以确保业务逻辑按要求工作。

LuceneConstants.java

这个类是用来提供可应用于示例应用程序中使用的各种常量。

package com.yiibai.lucene;

public class LuceneConstants {
   public static final String CONTENTS="contents";
   public static final String FILE_NAME="filename";
   public static final String FILE_PATH="filepath";
   public static final int MAX_SEARCH = 10;
}

Searcher.java

这个类用来读取就使用Lucene库的原始数据，并搜索数据的索引。

package com.yiibai.lucene;

import java.io.File;
import java.io.IOException;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
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.Sort;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

public class Searcher {

IndexSearcher indexSearcher;
   QueryParser queryParser;
   Query query;

   public Searcher(String indexDirectoryPath) throws IOException{
      Directory indexDirectory
         = FSDirectory.open(new File(indexDirectoryPath));
      indexSearcher = new IndexSearcher(indexDirectory);
      queryParser = new QueryParser(Version.LUCENE_36,
         LuceneConstants.CONTENTS,
         new StandardAnalyzer(Version.LUCENE_36));
   }

   public TopDocs search( String searchQuery)
      throws IOException, ParseException{
      query = queryParser.parse(searchQuery);
      return indexSearcher.search(query, LuceneConstants.MAX_SEARCH);
   }

   public TopDocs search(Query query)
      throws IOException, ParseException{
      return indexSearcher.search(query, LuceneConstants.MAX_SEARCH);
   }

   public TopDocs search(Query query,Sort sort)
      throws IOException, ParseException{
      return indexSearcher.search(query,
         LuceneConstants.MAX_SEARCH,sort);
   }

   public void setDefaultFieldSortScoring(boolean doTrackScores,
      boolean doMaxScores){
      indexSearcher.setDefaultFieldSortScoring(
         doTrackScores,doMaxScores);
   }

   public Document getDocument(ScoreDoc scoreDoc)
      throws CorruptIndexException, IOException{
      return indexSearcher.doc(scoreDoc.doc);
   }

   public void close() throws IOException{
      indexSearcher.close();
   }
}

LuceneTester.java

这个类是用来测试Lucene库的搜索能力。

package com.yiibai.lucene;

import java.io.IOException;

import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.TopDocs;

public class LuceneTester {

   String indexDir = "E:\Lucene\Index";
   String dataDir = "E:\Lucene\Data";
   Indexer indexer;
   Searcher searcher;

   public static void main(String[] args) {
      LuceneTester tester;
      try {
          tester = new LuceneTester();
          tester.sortUsingRelevance("cord3.txt");
          tester.sortUsingIndex("cord3.txt");
      } catch (IOException e) {
          e.printStackTrace();
      } catch (ParseException e) {
          e.printStackTrace();
      }
   }

   private void sortUsingRelevance(String searchQuery)
      throws IOException, ParseException{
      searcher = new Searcher(indexDir);
      long startTime = System.currentTimeMillis();
      //create a term to search file name
      Term term = new Term(LuceneConstants.FILE_NAME, searchQuery);
      //create the term query object
      Query query = new FuzzyQuery(term);
      searcher.setDefaultFieldSortScoring(true, false);
      //do the search
      TopDocs hits = searcher.search(query,Sort.RELEVANCE);
      long endTime = System.currentTimeMillis();

      System.out.println(hits.totalHits +
         " documents found. Time :" + (endTime - startTime) + "ms");
      for(ScoreDoc scoreDoc : hits.scoreDocs) {
         Document doc = searcher.getDocument(scoreDoc);
         System.out.print("Score: "+ scoreDoc.score + " ");
         System.out.println("File: "+ doc.get(LuceneConstants.FILE_PATH));
      }
      searcher.close();
   }

   private void sortUsingIndex(String searchQuery)
      throws IOException, ParseException{
      searcher = new Searcher(indexDir);
      long startTime = System.currentTimeMillis();
      //create a term to search file name
      Term term = new Term(LuceneConstants.FILE_NAME, searchQuery);
      //create the term query object
      Query query = new FuzzyQuery(term);
      searcher.setDefaultFieldSortScoring(true, false);
      //do the search
      TopDocs hits = searcher.search(query,Sort.INDEXORDER);
      long endTime = System.currentTimeMillis();

      System.out.println(hits.totalHits +
      " documents found. Time :" + (endTime - startTime) + "ms");
      for(ScoreDoc scoreDoc : hits.scoreDocs) {
         Document doc = searcher.getDocument(scoreDoc);
         System.out.print("Score: "+ scoreDoc.score + " ");
         System.out.println("File: "+ doc.get(LuceneConstants.FILE_PATH));
      }
      searcher.close();
   }
}

数据和索引目录的创建

从record1.txt到record10.txt的文件中包含简单的名称以及学生的其他细节，并把它们放在目录E:LuceneData。这是测试数据。索引目录路径应创建为E:LuceneIndex。期间，运行 Lucene索引程序后- 索引过程中，可以看到该文件夹中创建的索引文件的列表。

运行程序：

一旦创建源，创造了原始数据，数据目录，索引目录和索引完成后，已经准备好这一步是编译和运行程序。要做到这一点，请LuceneTester.Java文件选项卡中使用Eclipse IDE可使用Run选项，或使用Ctrl+ F11来编译和运行应用程序LuceneTester。如果您的应用程序一切正常，这将在Eclipse IDE的控制台打印以下消息：

10 documents found. Time :31ms
Score: 1.3179655 File: E:LuceneData
ecord3.txt
Score: 0.790779 File: E:LuceneData
ecord1.txt
Score: 0.790779 File: E:LuceneData
ecord2.txt
Score: 0.790779 File: E:LuceneData
ecord4.txt
Score: 0.790779 File: E:LuceneData
ecord5.txt
Score: 0.790779 File: E:LuceneData
ecord6.txt
Score: 0.790779 File: E:LuceneData
ecord7.txt
Score: 0.790779 File: E:LuceneData
ecord8.txt
Score: 0.790779 File: E:LuceneData
ecord9.txt
Score: 0.2635932 File: E:LuceneData
ecord10.txt
10 documents found. Time :0ms
Score: 0.790779 File: E:LuceneData
ecord1.txt
Score: 0.2635932 File: E:LuceneData
ecord10.txt
Score: 0.790779 File: E:LuceneData
ecord2.txt
Score: 1.3179655 File: E:LuceneData
ecord3.txt
Score: 0.790779 File: E:LuceneData
ecord4.txt
Score: 0.790779 File: E:LuceneData
ecord5.txt
Score: 0.790779 File: E:LuceneData
ecord6.txt
Score: 0.790779 File: E:LuceneData
ecord7.txt
Score: 0.790779 File: E:LuceneData
ecord8.txt
Score: 0.790779 File: E:LuceneData
ecord9.txt