热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Lucene索引功能

Lucene数据建模基本概念文档(doc):文档是Lucene索引和搜索的原子单元,文档是一个包含多个域的容器。域(field): 域包含“真正的”被搜索的内容,每一个域都有一个标

Lucene 数据建模

基本概念

文档(doc): 文档是 Lucene 索引和搜索的原子单元,文档是一个包含多个域的容器。

域(field): 域包含“真正的”被搜索的内容,每一个域都有一个标识名称,而“域值”则是实际被搜索的对象。

词元(term): 每个域的域值可能为一个复合字符串,通过分析器的各种处理,能将其分解为可以被搜索的词元。例如:"中国人China",其中包含的词元有:"中"、"国"、"人"、"china"。

与数据库的比较

灵活的架构: Lucene 没有一个确定的全局模式,加入索引的每一个文档都是独立的,与之前加入的文档没有任何关系。

反向规格化: Lucene 需要解决文档真实结构和 Lucene 表示能力之间的不匹配问题。因为 Lucene 文档都是单一文档,互相没有关系。无法像数据库中通过键将不同的表关联起来。

 

索引过程

流程示意

Lucene 索引功能

Lucene 索引功能

  • 提取文本和创建文档:从各种原始数据,比如 XML 文档、syslog 日志、网络数据包等提取出预想的文本信息并建立起对应的、包含各个域的文档。
  • 分析文档:将文本数据分割为词汇单元串,然后执行一些可选操作(转小写、去掉 a/an/the/on/in 等),得到能够被搜索的词元(term)。
  • 向索引添加文档:对输入数据分析完毕后就可以将分析结果写入索引文件中。
  • Lucene 的索引是倒排索引,倒排索引回答"哪些文档包含XXX词元"这样的问题,而不是回答"XXX文档包含有哪些词元"。

 

倒排索引

分词:

为了创建倒排索引,需要先将各文档(docs)中域(field)的值切分为独立的单词(term),而后将之创建为一个无重复的有序单词列表。这个过程称之为“分词(tokenization)”。

标准化:

为了实现 full-text 域的搜索,倒排索引中的数据还需进行“标准化(normalization)”为标准格式,才能评估其与用户搜索请求字符串的相似度。

例如,将所有大写字符转换为小写,将复数统一为单数,将同义词统一进行索引,去掉类似 the/is/a/ 等这样的 "停用词(stopword)" 等。

分析:

“分词” 和 “正规化” 过程被称为分析,由 Analyzer 完成。

Lucene 索引功能

索引结构:

index:一个索引存放在一个目录中。

segment:一个索引中可以有多个段,段与段之间是独立的,添加新的文档可能产生新段,不同的段可以合并成一个新段。

document:文档是创建索引的基本单位,不同的文档保存在不同的段中,一个段可以包含多个文档。

field:域,一个文档包含不同类型的信息,可以拆分开索引。

term:词,索引的最小单位,是经过词法分析和语言处理后的数据。

索引正向信息:

按照层次依次保存了从索引到词的包含关系:

index-->segment-->document-->field-->term。

索引反向信息

反向信息保存了词典的倒排表映射:

term-->document

索引结构图: 

Lucene 索引功能

 

基本索引操作

向索引添加文档:

  • addDocument(Document)                 ————使用默认分析器添加文档,该分析器在创建IndexWriter对象时指定,用于词汇单元化操作
  • addDocument(Document, Analyzer)       ————使用指定的分析器添加文档和词汇单元化操作

删除索引中的文档:

  • deleteDocuments(Term)                    ————删除包含 term 的所有文档
  • deleteDocuments(Term[])                  ————删除包含 term 数组任意元素的所有文档
  • deleteDocuments(Query)                   ————删除匹配查询语句的所有文档
  • deleteDocuments(Query[])                 ————删除匹配查询语句数组任意元素的所有文档
  • deleteAll(term)                         ————删除索引中所有文档

跟更新索引中的文档:

Lucene 只能删除整个旧文档再重新添加新文档,即便是更新 API 实际执行的操作也是如此。

  • updateDocument(Term, Document)                  ————先删除包含 term 变量的文档,在使用 writer 的默认分析器添加新文档
  • updateDocument(Term, Document, Analyzer)        ————功能与上面一致,不过可以指定分析器

 

域选项

域索引选项:

通过倒排索引来控制域文本是否可以被搜索。

  • Index.ANALYZED                                ————使用分析器将域值分解成独立的词汇单元流
  • Index.ANALYZED_NO_NORMS                       ————同上,不过不在索引中存储 norems 信息,可节省内存
  • Index.NOT_ANALYZED                            ——————不对 string 进行分析,将域值作为单一次元进行索引
  • Index.NOT_ANALYZED_NO_NORMS                   ——————同上,不过不在索引中存储norems信息,可节省内存
  • Index.NO                                      ——————使得对应域不可搜索

域存储选项:

用来确定是否需要存储域的真实值以便后续搜索时能恢复这个值。

  • Store.YES————指定存储域值,原始的字符串值全部被保存在索引中
  • Store.NO——————指定不存储域值

域的项向量选项:

Reader、TokenStream、byte[]域值:

域排序选项:

多值域:

 

对文档和域进行加权操作

当改变一个文档或域的加权因子时,必须完全删除并创建对应的文档,或者使用 updateDocument(起始也是删除再新建)方法。

文档加权操作:

通过文档加权因子,能够指示Lucene在计算相关性时考虑该文档针对索引中其它文档的重要程度。

  • Document 的 setBoost(float) 方法

域加权操作:

通过域加权因子,能够指示Lucene在计算相关性时考虑该文档针对索引中其它文档的重要程度

  • Field 的 setBoost(float) 方法

加权基准(Norms):

 

索引数字、日期和时间

索引数字:

  • 在字符串中包含数字:通过选择分析器(有些分析器会把"It is a long time from 1900"中的数字去掉,不解析为词元)来保证字符串中的数字不被丢弃,而被当成一个 string 类型的词元(term)
  • 只包含数字的域:要实现对数字域的范围搜索和排序,需要 NumericField 的 set 方法设置域类型为 long/int/float 之一

索引日期和时间:

  • Lucene 首先将他们转换为数值类型(Unix 时间戳)再进行索引

 

域截取

对一些文档,比如二进制数据,解析失败可能会导致在索引创建大量的无用的域,域截取可以加以控制,以下为2个默认实例。

  • MaxFieldLength.UNLIMITED     ————不采取截取
  • MaxFieldLength.LIMITED       ————截取前1000项

 

其它 Directory 子类

Lucene 的抽象类 Directory 提供了一个简单的文件存储 API,当操作索引文件进行读写时候,需要调用 Directory 子类的对应方法来进行。

子类负责从文件系统中读写文件,都是继承于抽象基类 FSDirectory。

  • SimpleFSDirectory      ————使用 java.io.* API 将文件存入文件系统
  • NIOFSDirectory         ————使用 java.nio.* API 将文件保存至文件系统
  • MMapDirectory          ————使用内存映射 I/O 进行文件访问
  • RAMDirectory           ————将所有文件都存入 RAM
  • FileSwitchDirectory    ————使用两个文件目录,根据文件扩展名在两个目录之间进行切换

 

高级索引话题

一些未细化讨论的Lucene索引的高级概念。包括:

  • 用IndexReader删除文档
  • 回收被删除文档的磁盘空间
  • 缓冲和刷新
  • 索引提交
  • ACID事务和索引连续性
  • 合并段

 


推荐阅读
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
  • 本文介绍了在mac环境下使用nginx配置nodejs代理服务器的步骤,包括安装nginx、创建目录和文件、配置代理的域名和日志记录等。 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
  • 纠正网上的错误:自定义一个类叫java.lang.System/String的方法
    本文纠正了网上关于自定义一个类叫java.lang.System/String的错误答案,并详细解释了为什么这种方法是错误的。作者指出,虽然双亲委托机制确实可以阻止自定义的System类被加载,但通过自定义一个特殊的类加载器,可以绕过双亲委托机制,达到自定义System类的目的。作者呼吁读者对网上的内容持怀疑态度,并带着问题来阅读文章。 ... [详细]
author-avatar
万象新动HR
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有