Lucene Payload 的研究与应用



Lucene Payload 的研究与应用
在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 相关的 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)

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

日期检索是区间检索的常见例子,如用户需要在图书馆中检索特定年代的图书,满足如下条件:
Date>1954/08/01 & Date<1955/08/01
常见的做法就是将日期作为一个独立 Field 进行存储,利用 RangeQuery 进行区间检索,Posting-list 的格式如图3中左图所示。如果图书日期分布区间很广,用 Field 存储日期信息,我们需要将日期细化到年月日进行存储,因此词条数目是非常庞大的。这种情况下,我们可以利用 Payload 功能来减少词条的数目,提高检索效率,可以将日期的年月作为词条,日作为 Payload 信息,这几乎将词条数目减小了近 30 倍,改进后的存储结构如图3右图所示:
图 3:使用 Payload 存储日期信息
使用 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);
Please read full article from Lucene Payload 的研究与应用

No comments:

Post a Comment

Labels

Algorithm (219) Lucene (130) LeetCode (97) Database (36) Data Structure (33) text mining (28) Solr (27) java (27) Mathematical Algorithm (26) Difficult Algorithm (25) Logic Thinking (23) Puzzles (23) Bit Algorithms (22) Math (21) List (20) Dynamic Programming (19) Linux (19) Tree (18) Machine Learning (15) EPI (11) Queue (11) Smart Algorithm (11) Operating System (9) Java Basic (8) Recursive Algorithm (8) Stack (8) Eclipse (7) Scala (7) Tika (7) J2EE (6) Monitoring (6) Trie (6) Concurrency (5) Geometry Algorithm (5) Greedy Algorithm (5) Mahout (5) MySQL (5) xpost (5) C (4) Interview (4) Vi (4) regular expression (4) to-do (4) C++ (3) Chrome (3) Divide and Conquer (3) Graph Algorithm (3) Permutation (3) Powershell (3) Random (3) Segment Tree (3) UIMA (3) Union-Find (3) Video (3) Virtualization (3) Windows (3) XML (3) Advanced Data Structure (2) Android (2) Bash (2) Classic Algorithm (2) Debugging (2) Design Pattern (2) Google (2) Hadoop (2) Java Collections (2) Markov Chains (2) Probabilities (2) Shell (2) Site (2) Web Development (2) Workplace (2) angularjs (2) .Net (1) Amazon Interview (1) Android Studio (1) Array (1) Boilerpipe (1) Book Notes (1) ChromeOS (1) Chromebook (1) Codility (1) Desgin (1) Design (1) Divide and Conqure (1) GAE (1) Google Interview (1) Great Stuff (1) Hash (1) High Tech Companies (1) Improving (1) LifeTips (1) Maven (1) Network (1) Performance (1) Programming (1) Resources (1) Sampling (1) Sed (1) Smart Thinking (1) Sort (1) Spark (1) Stanford NLP (1) System Design (1) Trove (1) VIP (1) tools (1)

Popular Posts