學(xué)校資源網(wǎng)站的建設(shè)方案/東莞seo推廣機(jī)構(gòu)帖子
前言
Lucene全文檢索主要分為索引、搜索兩個(gè)過程,對(duì)于索引過程就是將文檔磁盤存儲(chǔ)然后按照指定格式構(gòu)建索引文件,其中涉及數(shù)據(jù)存儲(chǔ)一些壓縮、數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)還是很巧妙的,下面主要記錄學(xué)習(xí)過程中的StoredField、DocValue以及磁盤BKD Tree的一些相關(guān)知識(shí)。
參考:
- https://juejin.cn/post/6978437292549636132
- https://juejin.cn/user/2559318800998141/posts
- Lucene 原理與代碼分析完整版.pdf
- https://lucene.apache.org/core/9_9_0/core/org/apache/lucene/codecs/lucene99/package-summary.html#package.description
- 美團(tuán)外賣搜索基于 Elasticsearch 的優(yōu)化實(shí)踐
目錄
- Lucene數(shù)據(jù)分類
- Lucene字段存儲(chǔ)
1、Lucene數(shù)據(jù)分類
在Lucene中索引數(shù)據(jù)存儲(chǔ)的邏輯層次有多個(gè)層次,從大到小依次是
- index:索引代表了一類數(shù)據(jù)的完整存儲(chǔ)
- segment: 一個(gè)索引可能有一個(gè)或者多個(gè)段構(gòu)成
- doc: segment中存儲(chǔ)的是一篇一篇的文檔doc,每個(gè)segment是一個(gè)doc的集合
- field: 每個(gè)doc都有多個(gè)field構(gòu)成,filed才包含了具體的文本,類似于一個(gè)json對(duì)象的一個(gè)屬性
- term: 每個(gè)field的值可以進(jìn)行分詞,進(jìn)而得到多個(gè)term,term是最基本的單元,每個(gè)field可以保存自己的詞向量,用來計(jì)算搜索相似度
按照數(shù)據(jù)的維度整個(gè)Lucene把需要處理的數(shù)據(jù)分為這么幾類
- PostingList,倒排表,也就是term->[doc1, doc3, doc5]這種倒排索引數(shù)據(jù)
- BlockTree, 從term和PostingList的映射關(guān)系,這種映射一般都用FST這種數(shù)據(jù)結(jié)構(gòu)來表示,這種數(shù)據(jù)結(jié)構(gòu)其實(shí)是一種樹形結(jié)構(gòu),類似于Tire樹,所以Lucene這里就叫BlockTree, 其實(shí)我更習(xí)慣叫它TermDict。
- StoredField ,一般類型的field原始數(shù)據(jù)存儲(chǔ)。
- DocValue 鍵值數(shù)據(jù),這種數(shù)據(jù)主要用于數(shù)值、日期類型的field,是用來加速對(duì)字段的排序、篩選的,列式存儲(chǔ)。
- TermVector詞向量信息,主要記一個(gè)不同term的全局出現(xiàn)頻率等信息,用于score,如搜索的str會(huì)被分為一個(gè)個(gè)term,然后會(huì)被轉(zhuǎn)為指定維度的向量,存儲(chǔ)文檔維護(hù)索引會(huì)根據(jù)當(dāng)前文檔、所有文檔中term出現(xiàn)的頻率以得到一個(gè)當(dāng)前term的權(quán)重創(chuàng)建一個(gè)對(duì)應(yīng)的指定維度的向量,然后就計(jì)算查詢相關(guān)性score。
- Norms用來存儲(chǔ)Normalisation信息, 比如給某些field加權(quán)之類的。
- PointValue 用來加速 range Query的信息。
一個(gè)段索引維護(hù)的數(shù)據(jù),Lucene9_9_0版本https://lucene.apache.org/core/9_9_0/core/org/apache/lucene/codecs/lucene99/package-summary.html#package.description
- Segment info. This contains metadata about a segment, such as the number of documents, what files it uses, and information about how the segment is sorted。其中包含有關(guān)片段的元數(shù)據(jù),例如文檔數(shù)量、它使用的文件以及有關(guān)片段排序方式的信息
- Field names. This contains metadata about the set of named fields used in the index.包含文檔fields的元數(shù)據(jù)以及名稱。
- Stored Field values. This contains, for each document, a list of attribute-value pairs, where the attributes are field names. These are used to store auxiliary information about the document, such as its title, url, or an identifier to access a database. The set of stored fields are what is returned for each hit when searching. This is keyed by document number.以文檔ID作為key,存儲(chǔ)當(dāng)前文檔的fields鍵值對(duì)。
- Term dictionary. A dictionary containing all of the terms used in all of the indexed fields of all of the documents. The dictionary also contains the number of documents which contain the term, and pointers to the term’s frequency and proximity data.包含所有文檔的所有索引字段中使用的所有term的字典。該詞典還包含包含該term的文檔數(shù)量,以及指向該術(shù)語的頻率和鄰近數(shù)據(jù)的指針。
- Term Frequency data. For each term in the dictionary, the numbers of all the documents that contain that term, and the frequency of the term in that document, unless frequencies are omitted (IndexOptions.DOCS)。term在當(dāng)前文檔出現(xiàn)的頻率以及在全部文檔出現(xiàn)的頻率,主要用于score得分,比如term在當(dāng)前文檔出現(xiàn)的頻率最高,在所有文檔出現(xiàn)的頻率最低,那么搜索該term在該文檔中搜索得分高。
- Term Proximity data. For each term in the dictionary, the positions that the term occurs in each document. Note that this will not exist if all fields in all documents omit position data。term出現(xiàn)在所有文檔的位置,可省略。
- Normalization factors. For each field in each document, a value is stored that is multiplied into the score for hits on that field.計(jì)算相關(guān)性score的時(shí)候可為某些field字段乘以一個(gè)系數(shù)。
- Term Vectors. For each field in each document, the term vector (sometimes called document vector) may be stored. A term vector consists of term text and term frequency. To add Term Vectors to your index see the Field constructors。每一個(gè)文檔的每一個(gè)field會(huì)有一個(gè)term向量,主要根據(jù)term出現(xiàn)的頻率計(jì)算出來,用于搜索的score分值計(jì)算。
- TextField: Reader or String indexed for full-text search。用于全文搜索。
- StringField: String indexed verbatim as a single token
- IntPoint: int indexed for exact/range queries.
- LongPoint: long indexed for exact/range queries.
- FloatPoint: float indexed for exact/range queries.
- DoublePoint: double indexed for exact/range queries.
- SortedDocValuesField: byte[] indexed column-wise for sorting/faceting,按列索引,用于排序
- SortedSetDocValuesField: SortedSet<byte[]> indexed column-wise for sorting/faceting
- NumericDocValuesField: long indexed column-wise for sorting/faceting
- SortedNumericDocValuesField: SortedSet indexed column-wise for sorting/faceting
- StoredField: Stored-only value for retrieving in summary results。僅存儲(chǔ)值。
- Per-document values. Like stored values, these are also keyed by document number, but are generally intended to be loaded into main memory for fast access. Whereas stored values are generally intended for summary results from searches, per-document values are useful for things like scoring factors.類似StoreField,可以更快加載到內(nèi)存訪問,用于搜索的摘要結(jié)果,但是每個(gè)文檔的值對(duì)于評(píng)分因素有很大的影響。
- Live documents. An optional file indicating which documents are live.一個(gè)可選文件,指定哪些文檔是實(shí)時(shí)的。主要用于段數(shù)據(jù)刪除時(shí)候,在段外部維護(hù)一個(gè)狀態(tài)記錄段的最新狀態(tài)。
- Point values. Optional pair of files, recording dimensionally indexed fields, to enable fast numeric range filtering and large numeric values like BigInteger and BigDecimal (1D) and geographic shape intersection (2D, 3D).可選的一對(duì)文件,記錄維度索引字段,以啟用快速數(shù)值范圍過濾和大數(shù)值,例如 BigInteger 和 BigDecimal (1D) 以及地理形狀交集(2D、3D)。
- Vector values. The vector format stores numeric vectors in a format optimized for random access and computation, supporting high-dimensional nearest-neighbor search.
按照數(shù)據(jù)存儲(chǔ)的方向維度可以分為
- 一般存儲(chǔ)形式:按層次保存了從索引,一直到詞的包含關(guān)系:索引(Index) –> 段(segment) –> 文檔 (Document) –> 域(Field) –> 詞(Term) ,層次結(jié)構(gòu),則每個(gè)層次都保存了本層次的信息以及下一層次的元信息。如StoredFileld、DocValue存儲(chǔ)形式。
- 反向存儲(chǔ)形式:如倒排索引(PostingList + BlockTree)數(shù)據(jù)存儲(chǔ)形式。
2、Lucene存儲(chǔ)文件
一個(gè)索引相關(guān)的存儲(chǔ)文件對(duì)應(yīng)一個(gè)文件夾,一個(gè)段的所有文件都具有相同的名稱和不同的擴(kuò)展名。擴(kuò)展名對(duì)應(yīng)于下面描述的不同文件格式。當(dāng)使用復(fù)合文件格式時(shí)(小段的默認(rèn)格式),這些文件(段信息文件、鎖定文件和文件夾文檔文件除外)將折疊為單個(gè).cfs文件。
- Segments info:多個(gè)段文件名永遠(yuǎn)不會(huì)重復(fù)使用。也就是說,當(dāng)任何文件保存到目錄時(shí), 以前從未使用過的文件名。這是使用簡單的生成方法實(shí)現(xiàn)的。比如說, 第一個(gè)段文件是segments_1,然后是segments_2,依此類推。生成是連續(xù)的長 以字母數(shù)字(以36為基數(shù))形式表示的整數(shù)。主要保存段的元信息,segments_N 保存了此索引包含多少個(gè)段,每個(gè)段包含多少篇文檔,實(shí)際的數(shù)據(jù)信息保存在field和詞中的。
- Write.lock:寫鎖默認(rèn)存儲(chǔ)在索引目錄中,名為“write.lock”。如果鎖目錄與索引目錄不同,則寫鎖將被命名為“XXXX-write.lock”,其中“”是從索引目錄的完整路徑導(dǎo)出的唯一前綴。如果存在此文件,則表示編寫者正在修改索引(添加或刪除文檔)。這個(gè)鎖文件確保一次只有一個(gè)writer修改索引。
- Fields、Field Index 、Field Data:This is keyed by document number.也就是上面說的一般存儲(chǔ)形式,保存了此段包含了多少個(gè)field,每個(gè)field的名稱及索引方式以及數(shù)據(jù)。
- Term Vector Index、Term Vector Data:當(dāng)你將字段設(shè)置為存儲(chǔ)Term Vector時(shí),Lucene會(huì)提取出該字段中每個(gè)詞項(xiàng)的相關(guān)信息,并將其存儲(chǔ)到倒排索引中。這樣可以在搜索時(shí)不僅找到包含關(guān)鍵詞的文檔,還能得知每個(gè)關(guān)鍵詞在文檔中的頻率和位置。因?yàn)椴粌H要根據(jù)倒排索引找到文檔ID,還需要計(jì)算文檔的相關(guān)性得分,會(huì)存儲(chǔ)當(dāng)前文檔全部term的頻率、位置信息,為了下一步也就是根據(jù)文檔內(nèi)全部的term的頻率信息計(jì)算下面的vector value。
- Vector values:根據(jù)每個(gè)文檔的所有term vector data數(shù)據(jù),為每個(gè)文檔計(jì)算出一個(gè)指定的相關(guān)性vector values,然后在跟query vevtor計(jì)算相關(guān)性score。
3、Lucene數(shù)據(jù)存儲(chǔ)
ps:學(xué)習(xí)分析Lucene版本為9_9_0
3.1、StoredField
In Lucene, fields may be stored, in which case their text is stored in the index literally, in a non-inverted manner. Fields that are inverted are called indexed. A field may be both stored and indexed.
保存字段屬性信息的,過程主要關(guān)注各數(shù)據(jù)類型是如何存儲(chǔ)的? 最終寫入索引是如何壓縮的?Lucene的field數(shù)據(jù)類型有下面幾大類
- int
- long
- Float
- Double
- String
- bytes
3.1.1、int
// TODO
3.1.2、long
3.1.3、Float
3.1.4、Double
3.1.5、String
3.1.6、bytes
3.2、DocValue
用于倒排查找的數(shù)據(jù),加速篩選和排序的,主要關(guān)注
- DocValue 的類型有哪些?SortedNumericDocValue?SortedSet?應(yīng)用場(chǎng)景等。
- DocValue是如何存儲(chǔ)的?