关闭

Lucene 入门详解

标签: lucene索引搜索
2311人阅读 评论(1) 收藏 举报
分类:
一. 索引

1. 索引流程
获取内容(爬虫等) —>
 
建立文档(获取内容转换成文档:标题、 征文、 摘要、 作者、 链接。 加权), 借助 Tika 框架可以方便地从 PDF、 Word 等中方便提取 —>
 
文档分析 (文本分割成语汇单元的独立原子元素, 和语言中的单词很像。 如何处理连接一体的各个单词呢?   是否需要进行语法修正? 是否需要插入同义词? 是否需要将单数和复数格式单词合并成同一个语汇单元? 常用词干提取器, running, run, runs 映射到 run) —>

文档索引 (文档加入索引列表)

2. 索引核心类
IndexWriter 是索引过程的核心组件。 可以理解为: 提供对索引文件的写入操作, 但不能用于读取或者搜索索引。 IndexWriter 需要开辟一定空间来存储索引, 该功能可以由 Directory 完成。

Director 类描述了 Lucene 索引的存放位置。 

Analyzer 负责从索引文本文件中提取语汇单元, 并提出剩下的无用信息。

Document 对表一些 Field 的集合。 可以理解为虚拟文档 - 比如 Web 页面、 Email 信息或者文本文件, 然后可以从中获取大量数据。  


3. 索引调试

使用 IndexWriter 的 setInfoStream(System.out)  该代码能够揭示有关段刷新和段合并的诊断信息, 可以帮助我们调整索引参数。  也可以使用 Luck 第三方工具来监视。 



二. 搜索

1. 搜索流程
搜索质量主要由查准率(过滤非相关文档能力)和查全率(查找相关文档的能力)来衡量。 


用户搜索界面:直观、 简洁。 最好的例子当然是 Google。 高亮关键词, 排序都至关重要 —>

建立查询(Build Query): Lucene 提供了一个称之为查询解析器(QueryParser)的强大开发包, 用它可以根据通用查询语法(布尔运算、 短语查询、 通配符)将用户输入的文本处理成查询对象。 在这期间, 也可以进行加权或者过滤, 如电商过滤掉脱销产品防止客户流到其他电商。 —>

搜索查询(Search Query): 查询检索索引并返回与查询语句匹配的文档, 结果返回时按照查询请求来排序。
常见搜索理论模型:
纯布尔模型 — 文档不管是否匹配查询请求, 都不会被评分。 即无序的, 仅是匹配文档的一个集合。
向量空间模型 — 查询语句和文档都是高维空间向量模型, 每一个独立项都是一个维度。 查询语句和文档之间的相关性或相似性由各自向量之间的距离计算得到。 
概率模型  采用全概率方法来计算文档和查询语句的匹配概率。


Lucene 并没有提供有关搜索范围的处理模块。 但 Solr 和 Nutch 都提供了对索引拆分和复制。 Katta 也能提供。 Elastic search 提供了另一个选择。


2. 搜索核心类

IndexSearcher 类用于搜索由 IndexWriter 类创建的索引。 最简单的搜索方法将单个 Query 对象和 int topN 计数作为参数, 返回一个 TopDocs 对象。

Term 搜索功能基本单元。

Query Lucene 含有 Query 的子类。 TermQuery, BooleanQuery、 PhraseQuery、 PrefixQuery、 PhrasePrefixQuery、 TermRangeQuery、 NumericRangeQuery、 FilteredQuery 和 SpanQuery。  



三. 代码实战

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.*;
import org.apache.lucene.search.*;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.RAMDirectory;

/** 
 * Lucene 检索内存索引
 *  
 * @author wenniuwuren
 *  
 */  
public class LuceneTest {
    public static void main(String[] args) throws IOException {  
        long startTime = System.currentTimeMillis();  

        // 新建一个内存目录对象
        Directory directory = new RAMDirectory();
        //Directory diskDirectory = new FSDirectory();

        //使用 IKAnalyzer 进行分词
        StandardAnalyzer analyzer = new StandardAnalyzer();
        IndexWriterConfig config = new IndexWriterConfig(analyzer);
        /* 
         * 创建索引写入对象,该对象既可以把索引写入到磁盘中也可以写入到内存中。 参数说明:
         * directory:目录对象,也可以是FSDirectory 磁盘目录对象  
         * config:分词器,分词器就是将检索的关键字分割成一组组词组,
         * 例子是 Lucene 自带的, 也可以使用第三方的分词器。
         */  
        IndexWriter writer = new IndexWriter(directory, config);

        // 创建Document 文档对象,在lucene中创建的索引可以看成数据库中的一张表,
        // 表中也可以有字段,往里面添加内容之后可以根据字段去匹配查询
        // 下面创建的doc对象中添加了三个字段,分别为name,sex,dosomething
        Document doc = new Document();  
        /* 
        *  参数说明 public Field(String name, String value, Store store, Index index)
        *  name : 字段名称
        *  value : 字段的值
        *
        *  store :
        *  Field.Store.YES:存储字段值(未分词前的字段值)可以用 IndexReader 恢复。 对于需要展示搜索结果的一些域很有用(URL、 标题)
        *  Field.Store.NO:不存储,存储与索引没有关系。 通常跟 Index.ANALYZED 选项共同来索引大的文本, 通常这些不需要恢复初始格式, 如 Wbe 页面征文
        *  Field.Store.COMPRESS:压缩存储,用于长文本或二进制,但性能受损。 CPU 计算时间换空间
        *
        *  index : 建立索引的方式,是否建立分词等等
        *  Field.Index.ANALYZED:分词建索引, 使每个分词可以被索引
        *  Field.Index.NOT_ANALYZED:不分词但是索引。 适用于不能被分解的值: URL、 社保号等。 尤其适用于精确搜索。
        *  Field.Index.ANALYZED_NO_NORMS:分词建索引,不在索引中存储 norms 信息。 norms 记录了索引中的 index-time boost 信息, 搜索时比较耗费内存
        *  Field.Index.NOT_ANALYZED_NO_NORMS:与 Field.Index.NOT_ANALYZED 相似, 但也不存储 norms(加权基准)。通常用于搜索期间节省索引空间和减少内存耗费。
         * Field.Index.NO -- 使对应的值不能被搜索
        */
        doc.add(new Field("name", "wenniuwuren", Field.Store.YES,Field.Index.ANALYZED));
        doc.add(new Field("sex", "男性", Field.Store.YES,Field.Index.NOT_ANALYZED));
        doc.add(new Field("dosometing", "I am learning lucene ",Field.Store.YES, Field.Index.ANALYZED));
        // 文档对象加入索引
        writer.addDocument(doc);
        writer.close(); // 这里可以提前关闭,因为dictory 写入内存之后 与IndexWriter 没有任何关系了  
  
        // 因为索引放在内存中,所以存放进去之后要立马测试,否则,关闭应用程序之后就检索不到了  
        // 创建IndexSearcher 检索索引的对象,里面要传递上面写入的内存目录对象directory

        // 打开索引文件  磁盘方式FSDirectory.open(new File()); IndexReader 开销较大, 建议搜友搜索期间使用同一个
        IndexReader reader =  DirectoryReader.open(directory);
        IndexSearcher searcher = new IndexSearcher(reader);

        // TermQuery 最基本的 Query 实现, 解析查询字符串
         Query query = new TermQuery(new Term("dosometing", "lucene"));
        // Query query = new TermQuery(new Term("sex", "男")); // 未分词, 搜索不到
        // Query query = new TermQuery(new Term("name", "wen"));  // 虽然分词了, 但是英文需要空格隔开才算一个分词, 搜索不到
          
        // 去索引目录中查询,返回的是 TopDocs 对象,里面存放的就是上面放的 document 文档对象的前(TOP)几个内容
        TopDocs result = searcher.search(query, 10);
        long endTime = System.currentTimeMillis();  
        System.out.println("总共花费" + (endTime - startTime) + "毫秒,检索到" + result.totalHits + "条记录。");
        for (int i = 0; i < result.scoreDocs.length; i++) {
            Document document = searcher.doc(result.scoreDocs[i].doc);

            System.out.println("name:" + document.getField("name").stringValue());
            System.out.println("sex:" + document.getField("sex").stringValue());
            System.out.println("dosomething:" + document.getField("dosometing").stringValue());

            // 对搜索结果评分细节
            Explanation explanation = searcher.explain(query, result.scoreDocs[i].doc);
            System.out.println(explanation.toString());
        }  
        writer.close();  
        directory.close();
    }  
}  



4
0
查看评论

Lucene教程

1、什么是“全文检索”(Full-Text Search)①全文检索的概念全文检索首先将要查询的目标文档中的词提取出来,组成索引,通过查询索引达到搜索目标文档的目的。这种先建立索引,再对索引进行搜索的过程就叫全文检索(Full-text Search)。全文检索(Full-Text Retrieva...
  • wanghanlincsdn
  • wanghanlincsdn
  • 2017-02-25 17:28
  • 189

用于Lucene的各中文分词比较

对几种中文分析器,从分词准确性和效率两方面进行比较。分析器依次为:StandardAnalyzer、ChineseAnalyzer、 CJKAnalyzer、IK_CAnalyzer、MIK_CAnalyzer、MMAnalyzer(JE分词)、PaodingAnalyzer。 单纯的中文分词的实...
  • hj7jay
  • hj7jay
  • 2015-12-02 14:12
  • 2994

lucene Ngram 划分词语

最近在做一个有关文本挖掘的项目,需要用到Ngram模型已经相对应的向量匹配相似度的技术 Ngram分词的程序 有位网友在问我,想了想写在这里吧,至于那些jar包也很好找,lucene jar ,在百度搜索都能找到 package edu.fjnu.huanghong; import java...
  • hhooong
  • hhooong
  • 2015-08-29 15:18
  • 1245

Lucene基础(一)--入门

Lucene介绍lucene的介绍,这里引用百度百科的介绍 Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种...
  • fun913510024
  • fun913510024
  • 2015-05-30 17:55
  • 1758

Lucene使用入门指南 (一)

Lucene的安装与配置的详细过程 第一步:下载安装JDK 在安装lucene之前需要首先安装jdk,因为lucene是在jdk的环境下运行的。最好下载jdk1.7以上的版本。这里我用的是jdk1.7.0_51。 1.首先从官网下载jdk1.7.0_51(下载之前先查看你的电脑是多...
  • qq_35522169
  • qq_35522169
  • 2016-09-07 15:45
  • 793

全文检索lucene中文分词的一些总结

<br /><br />全文检索几乎是所有内容管理系统软件(CMS)必备的功能,在对公司的CMS产品的开发维护过程中,全文检索始终是客户重点关注的模块,为满足客户各式各样越来越高的要求,对全文检索曾做过一段时间相对深入的研究,尤其是对分词机制,趁如今换工作比较空闲之际做个简单...
  • buptdavid
  • buptdavid
  • 2010-08-27 09:24
  • 13868

Lucene中常用中文分词器对比

01 基本介绍: paoding : Lucene中文分词“庖丁解牛” Paoding Analysis imdict : imdict智能词典所采用的智能中文分词程序 mmseg4j : 用 Chih-Hao Tsai 的 MMSeg 算法实现的中文分词器 ik : 采用了特...
  • jieshaowang1229
  • jieshaowang1229
  • 2015-06-04 07:37
  • 735

Lucene(入门一)

什么是Lucene?Lucene是apache软件基金会发布的一个开放源代码的全文检索引擎工具包,由资深全文检索专家Doug Cutting所撰写,它是一个全文检索引擎的架构,提供了完整的创建索引和查询索引,以及部分文本分析的引擎,Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便在...
  • zxiang248
  • zxiang248
  • 2016-08-12 15:25
  • 685

4、Lucene 入门程序及api 的说明

1.1 需求 实现一个资源管理器的搜索功能,通过关键字搜索,凡是文件名或文件内容包括关键字的文件都要找出来。 注意:该入门程序只对文本文件(.txt)搜索。  1.2 开发环境  Jdk:1.7.0_72以上的版本  Lucene包: lucene-core-4.10....
  • u013115157
  • u013115157
  • 2016-12-13 15:31
  • 653

lucene 4.x 使用N-Gram模型分词器实例。

N-Gram模型: N-Gram是大词汇连续语音识别中常用的一种语言模型,对中文而言,我们称之为汉语语言模型(CLM, Chinese Language Model)。汉语语言模型利用上下文中相邻词间的搭配信息,在需要把连续无空格的拼音、笔划,或代表字母或笔划的数字,转换成汉字串(即句子)时,可以...
  • earbao
  • earbao
  • 2014-12-02 11:37
  • 4469
    个人资料
    • 访问:346031次
    • 积分:5119
    • 等级:
    • 排名:第6475名
    • 原创:138篇
    • 转载:3篇
    • 译文:5篇
    • 评论:108条
    文章分类
    最新评论