lucene的DocValues不一樣於document文檔級別的存儲,它是一個面向列的存儲結構,提供從文檔編號到值的映射功能。根據不一樣的數據類型和應用場景支持多個DocValuesField類型,SortedDocValuesField即是其中之一,主要的做用是提供字符串值的排序功能(如根據檢索條件篩選出結果集後根據某個字符類型的字段進行排序)。算法
先說明一下SortedDocValuesField存儲的邏輯結構:.net
給定三個文檔doc[0]='abc',doc[1]='abd',doc[2]='abc',值通過排序去重後變成'abc'=0,'abd'=1,那麼原始的三篇文檔會變成doc[0]=0,doc[1]=1,doc[2]=0。在這樣的結構下排序尤爲是海量數據時候,無需將原始數據讀取到內存中進行排序,只需根據文檔的ID號從磁盤中讀取排序字段的序號,而後經過優先級隊列取前N條記錄便可。指針
SortedDocValuesField存儲的物理結構主要包含如下幾個步驟:blog
一、首先dvd數據文件會寫入文檔->序號的對應關係,dvm索引文件會記錄相應的文件指針(表明dvd文件的XXX-XXX部分記錄的是對應關係)排序
二、而後dvd數據文件會寫入已去重並排好序的具體的值,因爲排好序,所以採用了前綴壓縮算法,而且在記錄先後綴長度的時候先儘可能用1個字節進行壓縮存儲(由於在大部分狀況下,排序的字段值通常長度都比較小,好比去掉格式符的字符串日期類型僅14位),前綴長度先採用低4位保存超過15後使用vint保存,後綴長度因爲最小值爲1所以先減去1在左移4位採用高4位進行保存超過16後使用vint保存。爲了保證前綴壓縮效率lucene是每隔16條記錄進行前綴壓縮一次,由於記錄越靠後公共的前綴越少採用前綴壓縮反而增長了佔用空間。索引
三、最後寫入可以根據詞典值隨機獲取詞典序號的索引數據。在寫入時lucene按照每1024條記錄採用前綴壓縮算法,而且只記錄前綴值。隊列
注意:因爲詞典值在寫入時採用了BytesRefHash,因此值的長度最大隻能是32766,詳細可參考談談lucene中的BytesRefHash。內存