`
beyondqinghua
  • 浏览: 42402 次
  • 性别: Icon_minigender_1
  • 来自: 南昌
社区版块
存档分类
最新评论

lucene初探(三):lucene详解及流程介绍

 
阅读更多

简介

Lucene是一套用于全文检索和搜寻的开源程式库,由Apache软件基金会支持和提供。Lucene提供了一个简单却强大的应用程式接口,能够做全文索引和搜寻。在Java开发环境里Lucene是一个成熟的免 
费开源工具。就其本身而言,Lucene是目前以及最近几年最受欢迎的免费Java资讯检索程式库。人们经常提到资讯检索程式库,虽然与搜寻引擎有关,但不应该将资讯检索程式库与搜索引擎相混淆。

特点及优势

作为一个开放源代码项目,Lucene从问世之后,引发了开放源代码社群的巨大反响,程序员们不仅使用它构建具体的全文检索应用,而且将之集成到各种系统软件中去,以及构建Web应用,甚至某些商业软件也采用了Lucene作为其内部全文检索子系统的核心。Lucene是一个高性能、可伸缩的信息搜索(IR)库。它可以为你的应用程序添加索引和搜索能力。

突出的优点

Lucene作为一个全文检索引擎,其具有如下突出的优点:
1)索引文件格式独立于应用平台。Lucene定义了一套以8位字节为基础的索引文件格式,使得兼容系统或者不同平台的应用能够共享建立的索引文件。
2)在传统全文检索引擎的倒排索引的基础上,实现了分块索引,能够针对新的文件建立小文件索引,提升索引速度。然后通过与原有索引的合并,达到优化的目的。
3)优秀的面向对象的系统架构,使得对于Lucene扩展的学习难度降低,方便扩充新功能。
4)设计了独立于语言和文件格式的文本分析接口,索引器通过接受Token流完成索引文件的创立,用户扩展新的语言和文件格式,只需要实现文本分析的接口。
5)已经默认实现了一套强大的查询引擎,用户无需自己编写代码即使系统可获得强大的查询能力,Lucene的查询实现中默认实现了布尔操作、模糊查询(Fuzzy Search)、分组查询等等。

索引的重要性

通常意义的索引定义:将文献中具有检索意义的事项(可以是人名、地名、词语、概念、或其他事项)按照一定方式有序编排起来,以供检索的工具书。
那么lucene建立索引的初衷也是一样的,优化过SQL的开发人员都知道,什么是全表扫描,什么是索引扫描,利用索引可以产生事半功倍的效果,极大的提高检索性能。假如你需要搜索大量的文件,你希望找到那些包含某个单词或词组的文件。你将如何去写一个程序实现这个功能?一个做法就是按顺序扫描每一个文件,搜索是否包含给定的单词或词组。但是这样的做法有很多缺陷的,其中最明显的就是在大量的文件存在的情况下,速度是令人无法接受的。这种情况下,索引产生了。为了搜索大量的文本,你首先要对这些文本以特定的结构存储,这种存储结构可以让你迅速的搜索,消除慢的顺序扫描的过程。这种存储结构就叫索引,将文本转换成特定结构存储的过程,就叫建立索引。

Lucene的索引是一种专门设计的数据结构,类似于字典的目录,某个词对应到某一页,查找的时候直接定位到那一页,速度就非常快,不用一页一页的翻去查找,通常作为一组索引文件存储在文件系统上。

如何利用索引搜索

在索引中搜索关键词,找到包含关键词的文档的过程就是搜索。搜索质量通常使用准确度和召回率来描述。所谓召回率是指一次搜索结果集合中符合用户要求的数目与和用户查询相关的总数之比,而准确率是指一次搜索结果集合中符合用户要求的数目与该次搜索结果总数之比。我们也需要考虑其他有关搜索的因素,比如速度和快速搜索大量文本的能力,单个和多项查询、短语查询、通配符、结果的排名和排序的支持也很重要。

我们先来一个创建索引的例子

这个例子需要引入一个apache commons io包,方便我们读取文件

maven配置

写道
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
</dependency>

 

写道
package com.iris.scm.lucene.test2;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Index;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.index.LogByteSizeMergePolicy;
import org.apache.lucene.index.LogMergePolicy;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;

public class IndexBuilder {

/**
* @param args
*/
public static void main(String[] args) throws Exception {
createIndex("D:\\lucene\\textfiles", "D:\\lucene\\LuceneTest2");
}

/**
* 将指定目录的文本全部记录到索引中.
*
* <pre>
* 创建索引的步骤:
* 1)创建存放索引的目录Directory
* 2)创建索引器配置管理类IndexWriterConfig
* 3)使用索引目录和配置管理类创建索引器
* 4)使用索引器将Document写到索引文件中
* </pre>
*
* @param filePath
* @param indexPath
* @throws Exception
*/
public static void createIndex(String filePath, String indexPath) throws Exception {

// 指定索引目录
File indexDir = new File(indexPath);
// 创建索引目录
Directory directory = FSDirectory.open(indexDir);
// 创建一个中文分词器
Analyzer analyzer = new IKAnalyzer();

// 创建索引配置器
IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_36, analyzer);
// 创建批量创建索引导入策略,类似数据库分批事务
LogMergePolicy mergePolicy = new LogByteSizeMergePolicy();
// 设置segment添加文档(Document)时的合并频率
// 值较小,建立索引的速度就较慢
// 值较大,建立索引的速度就较快,>10适合批量建立索引
mergePolicy.setMergeFactor(50);
// 设置segment最大合并文档(Document)数
// 值较小有利于追加索引的速度
// 值较大,适合批量建立索引和更快的搜索
mergePolicy.setMaxMergeDocs(5000);
// 启用复合式索引文件格式,合并多个segment
mergePolicy.setUseCompoundFile(true);
indexWriterConfig.setMergePolicy(mergePolicy);

// 设置索引的打开模式
indexWriterConfig.setOpenMode(OpenMode.CREATE_OR_APPEND);

// 创建索引器
IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig);

List<Map<String, String>> list = readerFiles(filePath);
for (Map<String, String> map : list) {

// Document是Lucene的文档结构,需要索引的对象都要转换为Document
Document document = new Document();
// 文件名,可查询,不分词,存储到索引库记录中
document.add(new Field("file_name", map.get("file_name"), Store.YES, Index.NOT_ANALYZED));
// 文件路径,可查询,不分词,存储到索引库记录中
document.add(new Field("file_path", map.get("file_path"), Store.YES, Index.NOT_ANALYZED));
// 文本内容,这里因为文件较小,直接存储到索引记录库,如果大文件不建议存储
document.add(new Field("content", map.get("content"), Store.YES, Index.ANALYZED));

// 把文档添加到索引库
indexWriter.addDocument(document);
}

indexWriter.close();
}

/**
* 读取指定目录下的文件文本内容.
*
* @param dir
* @return
* @throws Exception
*/
public static List<Map<String, String>> readerFiles(String dir) throws Exception {

File dirFile = new File(dir);
File[] files = dirFile.listFiles();
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
for (File file : files) {
// 目录,退出
if (file.isDirectory()) {
continue;
}
Map<String, String> map = new HashMap<String, String>();
// 读取文件内容
String content = FileUtils.readFileToString(file);
map.put("file_name", file.getName());
map.put("file_path", file.getPath());
map.put("content", content);
list.add(map);
}
return list;

}
}

 

 再来一个检索索引的例子

 

 

 

写道
package com.iris.scm.lucene.test2;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
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;
import org.wltea.analyzer.lucene.IKAnalyzer;

public class IndexQuery {

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

List<Map<String, String>> list1 = query("D:\\lucene\\LuceneTest2", "重金属");
System.out.println("检索式关键词:重金属");
printFileInfo(list1);

List<Map<String, String>> list2 = query("D:\\lucene\\LuceneTest2", "商业化生物");
System.out.println("检索式关键词:商业化生物");
printFileInfo(list2);
}

public static void printFileInfo(List<Map<String, String>> list) {

for (Map<String, String> map : list) {
System.out.println("文件名:" + map.get("file_name"));
System.out.println("文件路径:" + map.get("file_path"));
System.out.println("文件内容:" + map.get("content"));
System.out.println();
System.out.println();
}
}

/**
* 利用创建的索引检索.
*
* <pre>
* 利用索引检索的步骤:
* 1)使用QueryParser将查询的关键词解析成Lucene的查询对象Query。创建QueryParser的时候我们需要用到分词器,这个分词器要和前面创建索引的时候使用的分词器一致。
* 2)使用FSDirectory打开索引所在的目录。
* 3)使用IndexReader读取索引目录和使用IndexSearcher进行搜索。
* 4)返回搜索结果对象TopDocs。TopDocs包含搜索到结果总数和结果的集合ScoreDocs数组
* 5)遍历结果的集合ScoreDocs数组,根据每一个ScoreDoc的文档编号获取Document
* </pre>
*
* @param idxDir
* @param keyword
* @return
* @throws Exception
*/
public static List<Map<String, String>> query(String idxDir, String keyword) throws Exception {

String[] fields = { "file_name", "content" };
// 创建一个分词器,和创建索引时用的分词器要一致
Analyzer analyzer = new IKAnalyzer();
// 创建查询解析器
QueryParser queryParser = new MultiFieldQueryParser(Version.LUCENE_36, fields, analyzer);
// 将查询关键词解析成Lucene的Query对象
Query query = queryParser.parse(keyword);

// 打开索引目录
File indexDir = new File(idxDir);
Directory directory = FSDirectory.open(indexDir);

// 获取访问索引的接口,进行搜索
IndexReader indexReader = IndexReader.open(directory);
IndexSearcher indexSearcher = new IndexSearcher(indexReader);

// TopDocs 搜索返回的结果
TopDocs topDocs = indexSearcher.search(query, 100);// 只返回前100条记录

int totalCount = topDocs.totalHits; // 搜索结果总数量
System.out.println("搜索到的结果总数量为:" + totalCount);
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
ScoreDoc[] scoreDocs = topDocs.scoreDocs; // 搜索的结果集合
for (ScoreDoc scoreDoc : scoreDocs) {
// 文档编号
int docID = scoreDoc.doc;
// 根据文档编号获取文档
Document doc = indexSearcher.doc(docID);
Map<String, String> map = new HashMap<String, String>();
map.put("file_name", doc.get("file_name"));
map.put("file_path", doc.get("file_path"));
map.put("content", doc.get("content"));
list.add(map);
}
indexReader.close();
indexSearcher.close();
return list;
}
}

 

分享到:
评论

相关推荐

    lucene-core-7.7.0-API文档-中文版.zip

    Maven坐标:org.apache.lucene:lucene-core:7.7.0; 标签:apache、lucene、core、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档...

    详解SpringBoot+Lucene案例介绍

    * lucene-core:Lucene的核心包,提供了基本的索引和搜索功能。 * lucene-queryparser:提供了查询解析的功能,用于将用户输入的查询语句转换为Lucene的查询对象。 * lucene-analyzers-common:提供了基础的分词器,...

    Lucene初探,一个初级的LuceneDemo

    **Lucene初探:一个初级的LuceneDemo** 在IT领域,搜索引擎技术是不可或缺的一部分,尤其是在大数据时代,高效的信息检索显得尤为重要。Apache Lucene就是这样一款强大的开源全文搜索引擎库,它为开发者提供了构建...

    lucene-sandbox-6.6.0-API文档-中文版.zip

    Maven坐标:org.apache.lucene:lucene-sandbox:6.6.0; 标签:apache、lucene、sandbox、jar包、java、中文文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译...

    lucene5.X与lucene3.60的版本差异

    《Lucene 5.x与3.6.0版本差异详解》 Lucene作为一个强大的全文搜索引擎库,其每个版本的更新都带来了一系列的变化和优化。本文将深入探讨Lucene 5.x与Lucene 3.6.0之间的主要差异,帮助开发者理解新版本的功能改进...

    Lucene.Heritrix:开发自己的搜索引擎(第2版)

    这本书详细介绍了利用Apache Lucene和Heritrix这两个强大的开源工具来创建自定义搜索引擎的技术和策略。 Apache Lucene是一个高性能、全文本搜索库,它提供了索引和搜索功能的核心实现。开发者可以将其嵌入到各种...

    lucene、lucene.NET详细使用与优化详解

    - 使用Segment:lucene通过Segment来分块存储索引,多段合并可以减少索引碎片,提高检索效率。 - 分布式索引和搜索:通过分布式部署,lucene可以处理大规模数据,提高系统的并发处理能力。 5. 应用场景 - 内容...

    Lucene 常用功能介绍视频详解

    **Lucene 常用功能介绍** Lucene 是一个高性能、全文检索库,由Apache软件基金会开发并维护。它提供了一个简单但功能强大的API,用于在各种应用中实现全文索引和搜索。以下是对Lucene常用功能的详细介绍: 1. **...

    Lucene开发详解.pdf

    ### Lucene开发详解 #### 一、Lucene简介 Lucene是一个高性能、全功能的文本搜索引擎库,由Doug Cutting创建并捐赠给Apache Software Foundation。它主要用于构建全文搜索应用程序,能够帮助开发者快速地在其应用...

    IKAnalyzer中文分词支持lucene6.5.0版本

    由于林良益先生在2012之后未对IKAnalyzer进行更新,后续lucene分词接口发生变化,导致不可使用,所以此jar包支持lucene6.0以上版本

    Lucene 7.2.1 官方jar包

    **Lucene 7.2.1 官方JAR包详解** Lucene 是一个高性能、全文本搜索库,由Apache软件基金会开发并维护。作为Java编写的一个开源项目,Lucene 提供了强大的文本分析和索引功能,广泛应用于各种搜索引擎的开发。版本...

    经典的lucene实例代码及详细解析以及lucene结构流程介绍

    经典的Lucene实例代码及详细解析以及Lucene结构流程介绍 Lucene是一个功能强大且灵活的开源搜索引擎库,它提供了一个简单易用的API,允许开发者快速构建搜索应用程序。下面将对Lucene的实例代码和结构流程进行详细...

    lucene-core-7.2.1-API文档-中文版.zip

    Maven坐标:org.apache.lucene:lucene-core:7.2.1; 标签:apache、lucene、core、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档...

    lucene中的SpanQuery和PhraseQuery详解(有图示)

    Lucene中的SpanQuery和PhraseQuery详解 Lucene是一个功能强大的搜索引擎库,提供了多种查询方式,其中SpanQuery和PhraseQuery是两个重要的查询类型。本文将详细介绍SpanQuery和PhraseQuery的使用和区别。 一、...

    Lucene 3.0 原理与代码分析PDF

    Lucene学习总结之三:Lucene的索引文件格式(1) Lucene学习总结之三:Lucene的索引文件格式(2) Lucene学习总结之三:Lucene的索引文件格式(3) Lucene学习总结之四:Lucene索引过程分析(1) Lucene学习总结之...

    lucene-core-6.6.0-API文档-中文版.zip

    Maven坐标:org.apache.lucene:lucene-core:6.6.0; 标签:core、apache、lucene、jar包、java、中文文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档...

    lucene-spatial-6.6.0-API文档-中文版.zip

    Maven坐标:org.apache.lucene:lucene-spatial:6.6.0; 标签:apache、lucene、spatial、jar包、java、中文文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译...

    lucene-misc-6.6.0-API文档-中文版.zip

    Maven坐标:org.apache.lucene:lucene-misc:6.6.0; 标签:apache、lucene、misc、jar包、java、中文文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档...

    Lucene 实时搜索视频详解

    1. **索引过程**:Lucene 的核心概念之一是建立索引,将原始文本数据转化为可快速查询的结构。这个过程包括分析(Analyzer)文本、分词、创建倒排索引等步骤。倒排索引允许我们快速定位包含特定词汇的文档。 2. **...

    中英文版 lucene in action (pdf 版,附随书源码)

    《Lucene in Action》是一本深受开发者欢迎的书籍,它深入浅出地介绍了Apache Lucene这个全文搜索引擎库的使用和实现原理。这本书分为中文和英文两个版本,为读者提供了全面了解和掌握Lucene的机会。PDF版包含了完整...

Global site tag (gtag.js) - Google Analytics