Lucene Payload 的研究与应用一

2023-11-10 17:08
文章标签 应用 研究 lucene payload

本文主要是介绍Lucene Payload 的研究与应用一,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

[i][b]http://www.ibm.com/developerworks/cn/opensource/os-cn-lucene-pl/index.html[/b][/i]Lucene Payload 的研究与应用

文档选项
打印本页

将此页作为电子邮件发送




级别: 初级

杨 筱强 (yangxq@cn.ibm.com), 软件工程师, IBM
马 蕤 (marui@cn.ibm.com), 软件工程师, IBM
赵 胜 (zhaos@cn.ibm.com), WebSphere Information Integrator部门经理, IBM中国软件开发中心


2008 年 11 月 06 日

Payload (元数据) 诞生于 Lucene 的2.2 版本,它是在 Lucene 2.1 索引文件格式的基础上扩展而来,提供了一种可以灵活配置的高级索引技术,在某些特定应用场景下能优化基于 Lucene 构建的应用的搜索性能。本文重点研究了 Payload 的实现原理、索引结构的变化、接口 API ,在本文的最后举例说明了 Payload 是如何帮助改善搜索体验的。
Lucene 是最初是由 Douglass R. Cutting 博士发布在自己主页上的一个 Java 全文信息检索工具包,后来成为 Apache Jakarta 家族中的一个开源项目,目前已经成为 Apache 基金会的顶级项目。索引是现代搜索引擎的核心,建立索引的过程就是把源数据处理成方便查询的索引文件的过程。 Lucene 采用的是一种被称为倒排索引 (Inverted Index) 的机制,倒排索引也是大多现代搜索引擎的基础。

Payload (元数据) 诞生于 Lucene 的2.2 版本,它是在 Lucene 2.1 索引文件格式的基础上扩展而来,提供了一种可以灵活配置的高级索引技术。本文重点研究了 Payload 的实现原理、索引结构的变化、接口 API ,在本文的最后举例说明了 Payload 是如何帮助改善搜索体验的。

Payload 的出现

倒排索引就是说我们维护了一个词条表,对于这个表中的每个词条,都有一个链表描述了有哪些文档包含了这个词条。假定我们有三篇文档 D0,D1,D2:

D0 = "it is what it is"
D1 = "what is it"
D2 = "it is a banana"



那么,我们可以创建如下倒排索引结构:

Term Posting-list
"a": {2}
"banana": {2}
"is": {0, 1, 2}
"it": {0, 1, 2}
"what": {0, 1}



一般情况下,将一个词条所索引的文档(一般用文档编号表示)称之为 Posting,那么一个词条索引的多个文档就称之为 Posting-list。除了在 Posting-list 中记录文档编号,Lucene 也在Posting-list 中添加了词频和位置信息。词频的添加有助于结果的排序,位置信息的添加解决了短语检索的问题。

在Lucene 2.1 中,记录位置信息的即 .prx 文件,它的格式如下:

ProxFile (.prx) --> <TermPositions> TermCount
TermPositions --> <Positions> DocFreq
Positions --> <PositionDelta> Freq
PositionDelta --> VInt



仔细观察我们可以发现,文档 D0 中 what 词条是加粗显示而文档 D1 中的 what 则没有。显然,Lucene 2.1 的索引结构是无法表示出两者的差异。为了解决这个问题,从 Lucene2.2 开始,引入了 Payload 的概念。 Payload 即词条 (Term) 的元数据或称载荷, Lucene 支持用户在索引的过程中将词条的元数据添加的索引库中,同时也提供了在检索结果时读取 Payload 信息的功能。Payload 的诞生为用户提供了一种可灵活配置的高级索引技术,为支持更加丰富的搜索体验创造了条件。

那么 Lucene 是如何改进索引文件以支持 Payload 功能的呢?


[img]http://www.ibm.com/developerworks/cn/opensource/os-cn-lucene-pl/images/image001.gif[/img]



回页首



索引结构的变化

为了更加形象的描述改进后的索引结构,我们用不同的颜色表示出文档 ID ,词频,位置和 Payload,如图 1 所示,(U表示下划线,B表示粗体)


图 1:Lucene的索引结构


对比 Lucene2.1 的索引结构,Lucene2.2 的索引结构的表达式如下:

ProxFile (.prx) --> <TermPositions> TermCount
TermPositions --> <Positions> DocFreq
Positions --> <PositionDelta,Payload?> Freq
Payload --> <PayloadLength?,PayloadData>
PositionDelta --> VInt
PayloadLength --> VInt
PayloadData --> bytePayloadLength



从上面的索引表达式中可以看出只有当一个词汇包含 Payload 信息时,Lucene 才会为之分配相应的 Payload 存储空间,这是一种高效率的空间实现。Lucene2.2 之后的 Payload 特指词条的元数据,那么文档的元数据如何表示呢?

我们知道,Lucene 中 Document 由 Field 组成,而 Field 由 Term 组成,文档的 Payload 可以用存储的 Field 表示。这样存在的问题是,如果需要读取大量的文档的元数据,因为 Field 的索引信息与存储信息是分开的,那么 I/O 效率将是较差的。而 Payload 信息则是直接存储在索引中,因此可以利用词条的 Payload 功能存储文档级别的元数据。文档级 Payload 可表示为如下图2所示格式(省略了词频和位置信息):


图 2:文档级的 Payload 表示


如图2所示,以文档的 url 信息为例,通过为每一个文档构造一个特殊的词条 ”url” ,将每个文档的 ur l值作为 payload 信息,把 Payload 与文档编号关联起来,这样就可以实现文档级的 Payload。





回页首



Payload 相关的 API

从 Lucene2.2 的索引结构可以看出,Payload 的存储与词条的位置信息是紧密联系在一起的,因此 Payload 的存储和检索 API 位于Token类和 TermPositions 类当中。

向词条中存储 Payload 信息

org.apache.lucene.analysis.Token
void setPayload(Payload payload)



Payload 信息的构造函数

org.apache.lucene.index.Payload
Payload(byte[] data)

Payload(byte[] data,
int offset,
int length)



从位置信息中检索 Payload

org.apache.lucene.index.TermPositions
boolean next();
int doc()
int freq();

int nextPosition();

int getPayloadLength();
byte[] getPayload(byte[] data,
int offset)






回页首



Payload 的应用场景举例

场景一:改进的 Lucene 的区间检索

日期检索是区间检索的常见例子,如用户需要在图书馆中检索特定年代的图书,满足如下条件:

Date>1954/08/01 & Date<1955/08/01



常见的做法就是将日期作为一个独立 Field 进行存储,利用 RangeQuery 进行区间检索,Posting-list 的格式如图3中左图所示。如果图书日期分布区间很广,用 Field 存储日期信息,我们需要将日期细化到年月日进行存储,因此词条数目是非常庞大的。这种情况下,我们可以利用 Payload 功能来减少词条的数目,提高检索效率,可以将日期的年月作为词条,日作为 Payload 信息,这几乎将词条数目减小了近 30 倍,改进后的存储结构如图3右图所示:


图 3:使用 Payload 存储日期信息


场景二:提高特定词汇的评分

利用 Payload 功能,还可以提高文档中特定词汇的评分,如黑体词汇、斜体词汇等,从而优化搜索结果排序。

下面还以文档 D0 和 D1 为例说明如何设置和检索 Payload。

D0 = "it is what it is"
D1 = "what is it"



Step1:在 Analyzer 处理过程中,为特殊词汇添加评分 Payload

final byte BoldBoost = 5;

final byte ItalicBoost = 5;

Token token = new Token(…);

if (isBold) {//如果是黑体字
token.setPayload(
new Payload(new byte[] {BoldBoost}));
}else if(isItalic){//如果是斜体字
token.setPayload(
new Payload(new byte[] { ItalicBoost }));
}

return token;



Step2:重写 Similarity (主要负责排名和评分)

Similarity boostingSimilarity =
new DefaultSimilarity() {
// @override
public float scorePayload(byte [] payload,
int offset,
int length) {

//读取payload的值,payload存储的即为词汇的评分。
if (length == 1) return payload[offset];
};



Step3:使用重写的 boostingSimilarity 进行检索

Query btq = new BoostingTermQuery(
new Term(“field”, “what”));


Searcher searcher = new IndexSearcher(…);
Searcher.setSimilarity(boostingSimilarity);

Hits hits = searcher.search(btq);

这篇关于Lucene Payload 的研究与应用一的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/384085

相关文章

Python使用Tkinter打造一个完整的桌面应用

《Python使用Tkinter打造一个完整的桌面应用》在Python生态中,Tkinter就像一把瑞士军刀,它没有花哨的特效,却能快速搭建出实用的图形界面,作为Python自带的标准库,无需安装即可... 目录一、界面搭建:像搭积木一样组合控件二、菜单系统:给应用装上“控制中枢”三、事件驱动:让界面“活”

如何确定哪些软件是Mac系统自带的? Mac系统内置应用查看技巧

《如何确定哪些软件是Mac系统自带的?Mac系统内置应用查看技巧》如何确定哪些软件是Mac系统自带的?mac系统中有很多自带的应用,想要看看哪些是系统自带,该怎么查看呢?下面我们就来看看Mac系统内... 在MAC电脑上,可以使用以下方法来确定哪些软件是系统自带的:1.应用程序文件夹打开应用程序文件夹

Python Flask 库及应用场景

《PythonFlask库及应用场景》Flask是Python生态中​轻量级且高度灵活的Web开发框架,基于WerkzeugWSGI工具库和Jinja2模板引擎构建,下面给大家介绍PythonFl... 目录一、Flask 库简介二、核心组件与架构三、常用函数与核心操作 ​1. 基础应用搭建​2. 路由与参

Spring Boot中的YML配置列表及应用小结

《SpringBoot中的YML配置列表及应用小结》在SpringBoot中使用YAML进行列表的配置不仅简洁明了,还能提高代码的可读性和可维护性,:本文主要介绍SpringBoot中的YML配... 目录YAML列表的基础语法在Spring Boot中的应用从YAML读取列表列表中的复杂对象其他注意事项总

电脑系统Hosts文件原理和应用分享

《电脑系统Hosts文件原理和应用分享》Hosts是一个没有扩展名的系统文件,当用户在浏览器中输入一个需要登录的网址时,系统会首先自动从Hosts文件中寻找对应的IP地址,一旦找到,系统会立即打开对应... Hosts是一个没有扩展名的系统文件,可以用记事本等工具打开,其作用就是将一些常用的网址域名与其对应

CSS 样式表的四种应用方式及css注释的应用小结

《CSS样式表的四种应用方式及css注释的应用小结》:本文主要介绍了CSS样式表的四种应用方式及css注释的应用小结,本文通过实例代码给大家介绍的非常详细,详细内容请阅读本文,希望能对你有所帮助... 一、外部 css(推荐方式)定义:将 CSS 代码保存为独立的 .css 文件,通过 <link> 标签

Python使用Reflex构建现代Web应用的完全指南

《Python使用Reflex构建现代Web应用的完全指南》这篇文章为大家深入介绍了Reflex框架的设计理念,技术特性,项目结构,核心API,实际开发流程以及与其他框架的对比和部署建议,感兴趣的小伙... 目录什么是 ReFlex?为什么选择 Reflex?安装与环境配置构建你的第一个应用核心概念解析组件

C#通过进程调用外部应用的实现示例

《C#通过进程调用外部应用的实现示例》本文主要介绍了C#通过进程调用外部应用的实现示例,以WINFORM应用程序为例,在C#应用程序中调用PYTHON程序,具有一定的参考价值,感兴趣的可以了解一下... 目录窗口程序类进程信息类 系统设置类 以WINFORM应用程序为例,在C#应用程序中调用python程序

Java应用如何防止恶意文件上传

《Java应用如何防止恶意文件上传》恶意文件上传可能导致服务器被入侵,数据泄露甚至服务瘫痪,因此我们必须采取全面且有效的防范措施来保护Java应用的安全,下面我们就来看看具体的实现方法吧... 目录恶意文件上传的潜在风险常见的恶意文件上传手段防范恶意文件上传的关键策略严格验证文件类型检查文件内容控制文件存储

CSS3 布局样式及其应用举例

《CSS3布局样式及其应用举例》CSS3的布局特性为前端开发者提供了无限可能,无论是Flexbox的一维布局还是Grid的二维布局,它们都能够帮助开发者以更清晰、简洁的方式实现复杂的网页布局,本文给... 目录深入探讨 css3 布局样式及其应用引言一、CSS布局的历史与发展1.1 早期布局的局限性1.2