lucene frq 文件

        lucene 的frq 存放的是搜索引擎中的doclist,主要保存了docid以及该id 出现的次数,当然为了加快检索,里面还建立的一个跳排表,我们这些进行详细介绍。

 

        一 docid 和 频率

 

          如果简单的来想,这块的内容可以很简单,就是一个 (docid+ freq ) 一个序列 :  docid1, freq1 ,docid2, freq2 , docid3, freq3 ................    

          但是lucene 对这块进行了优化,节省很多的空间。 

          首先引用别人的分析,讲的很详细:http://forfuture1978.iteye.com/blog/546841

 

          For example, the TermFreqs for a term which occurs once in document seven and three times in document eleven, with omitTf false, would be the following sequence of VInts: 15, 8, 3 If omitTf were true it would be this sequence of VInts instead: 7,4 首先我们看omitTf=false的情况,也即我们在索引中会存储一个文档中term出现的次数。 例子中说了,表示在文档7中出现1次,并且又在文档11中出现3次的文档用以下序列表示:15,8,3. 那这三个数字是怎么计算出来的呢? 首先,根据定义TermFreq --> DocDelta[, Freq?],一个TermFreq结构是由一个DocDelta后面或许跟着Freq组成,也即上面我们说的A+B?结构。 DocDelta自然是想存储包含此Term的文档的ID号了,Freq是在此文档中出现的次数。 所以根据例子,应该存储的完整信息为[DocID = 7, Freq = 1] [DocID = 11, Freq = 3](见全文检索的基本原理章节)。 然而为了节省空间,Lucene对编号此类的数据都是用差值来表示的,也即上面说的规则2,Delta规则,于是文档ID就不能按完整信息存了,就应该存放如下: [DocIDDelta = 7, Freq = 1][DocIDDelta = 4 (11-7), Freq = 3] 然而Lucene对于A+B?这种或然跟随的结果,有其特殊的存储方式,见规则3,即A+B?规则,如果DocDelta后面跟随的Freq为1,则用DocDelta最后一位置1表示。 如果DocDelta后面跟随的Freq大于1,则DocDelta得最后一位置0,然后后面跟随真正的值,从而对于第一个Term,由于Freq为1,于是放在DocDelta的最后一位表示,DocIDDelta = 7的二进制是000 0111,必须要左移一位,且最后一位置一,000 1111 = 15,对于第二个Term,由于Freq大于一,于是放在DocDelta的最后一位置零,DocIDDelta = 4的二进制是0000 0100,必须要左移一位,且最后一位置零,0000 1000 = 8,然后后面跟随真正的Freq = 3。 于是得到序列:[DocDleta = 15][DocDelta = 8, Freq = 3],也即序列,15,8,3。 如果omitTf=true,也即我们不在索引中存储一个文档中Term出现的次数,则只存DocID就可以了,因而不存在A+B?规则的应用。 [DocID = 7][DocID = 11],然后应用规则2,Delta规则,于是得到序列[DocDelta = 7][DocDelta = 4 (11 - 7)],也即序列,7,4.

 

          我们回过头再看看源代码:

           lucene/index/FormatPostingsDocsWriter.java

 

           @Override FormatPostingsPositionsConsumer addDoc(int docID, int termDocFreq) throws IOException { //计算docId差值 final int delta = docID - lastDocID; if (docID < 0 || (df > 0 && delta <= 0)) throw new CorruptIndexException("docs out of order (" + docID + " <= " + lastDocID + " )"); //写跳表 if ((++df % skipInterval) == 0) { // TODO: abstraction violation skipListWriter.setSkipData(lastDocID, storePayloads, posWriter.lastPayloadLength); skipListWriter.bufferSkip(df); } assert docID < totalNumDocs: "docID=" + docID + " totalNumDocs=" + totalNumDocs; lastDocID = docID; //不要frq 和 pos if (omitTermFreqAndPositions) out.writeVInt(delta); //req 是1,采用或然规则,节省空间 else if (1 == termDocFreq) out.writeVInt((delta<<1) | 1); //docid 和词频 else { out.writeVInt(delta<<1); out.writeVInt(termDocFreq); } return posWriter; }

 

           1  计算docid 差值

 

           2  根据是否frq以及frq值做不通的处理

 

 

二  跳表

 

       这款暂时还不是很懂,以后学习了再些

 

 

 

你可能感兴趣的:(优化,搜索引擎,Lucene,存储,文档,全文检索)