官术网_书友最值得收藏!

3.5.3 文檔值

FieldCache是索引的正向視圖,也就是文檔編號→值的視圖。FieldCache需要從倒排索引中解析出值,如圖3-16所示。

圖3-16 從倒排索引解析出值

可以輕松地使用FieldCache加載某一特定列的本地值數組。例如,如果每個文檔有一個字段為weight,也就是PageRank值列。

        Field f = new Field("weight", doc.pageRank ,
              Field.Store.YES, Field.Index.UN_TOKENIZED,
              Field.TermVector.NO);

則可以這樣得到所有文檔的權重:

        float[] weights = FieldCache.DEFAULT.getFloats(reader, "weight");

然后,每當需要知道一個文檔的權重值時,只需參考weights[docID]。

FieldCache支持許多本地類型:字節、短整型、長整型、浮點數、雙精度和StringIndex類,其中包括字符串值的排序順序。

第一次訪問給定的reader和列的field cache時,將訪問所有文檔的值,并作為一個獨立的大數組加載到內存中。值記錄到一個以reader實例和列名作為鍵的內部緩存中。因為要從倒排索引中解析出值,所以對大的索引來說,加載過程很耗時。

IndexDocValues不需要從倒排索引中解析出值,因為在建立索引時提供了一個文檔到值的映射。IndexDocValues允許在文檔索引時,可以更多地控制數據。每一個普通的Lucene列接收一個類型的值,以列的方式存儲。通過ValueType指定某個列的IndexDocValues類型,例如長整型、浮點型或者字節數組。

對整數類型,IndexDocValues提供字節對齊的變體,如8, 16, 32和64位,以及壓縮的PackedInts。對于浮點值,當前只提供float 32和float 64。但是對于字節數組值,IndexDocValues提供更靈活的存取方式。

可以指定值是否有固定或可變的長度,這些值是否應直接存儲,或以取消引用的方式存儲,這樣在不同值的數很少的情況下可以得到良好的壓縮。

因為不需要從倒排索引中解倒排或者解析值,所以IndexDocValues的加載速度很快。

FieldCache只能完全位于內存中,而IndexDocValues可以完全在內存或者位于硬盤。IndexDocValues提供同樣的隨機讀出接口。

讀出數據的性能依賴于值的類型。如果選擇使用PackedInts壓縮整數,就要付出代價。但是如果選擇32位對齊的變體,則就好像Java NIO ByteBuffers一樣訪問底層數組。通過Source.getArray()方法訪問數據。

        IndexReader r = IndexReader.open(w, true);
        DocValues docValues = MultiDocValues.getDocValues(r, field);
        Source source = docValues.getSource();


        byte[] values = (byte[]) source.getArray();

有很多應用可以受益于IndexDocValues,例如靈活的評分、分類統計、排序、合并和結果分組這樣的搜索功能。

一般來說,當有像排序、分類統計和分組結果這樣的功能要實現時,通常需要額外的專用列。以作者列為例,可以為了全文檢索而對這個列分詞,但這可能會導致分類統計或分組結果出現意外。然而,只需簡單地添加一個非分詞列就能解決這個問題。非分詞列往往用facet_author這樣的前綴命名。

IndexDocValues是不分詞的,所以可以簡單地增加一個同名的IndexDocValuesField來達到和額外列同樣的效果。使用IndexDocValues后,就能用更少的邏輯列實現同樣的功能。

默認Lucene使用FieldCache,除非聲明SortField.setUseIndexValues(boolean)。

        IndexSearcher searcher = new IndexSearcher(...);
        SortField field = new SortField("myField", SortField.Type.STRING);
        field.setUseIndexValues(true); //使用IndexValues實現排序
        Sort sort = new Sort(field);
        TopDocs topDocs = searcher.search(query, sort);
主站蜘蛛池模板: 冕宁县| 卓资县| 南通市| 南溪县| 安化县| 洞头县| 神池县| 安龙县| 长岛县| 张家川| 荆门市| 无锡市| 城固县| 阳山县| 寿阳县| 阿勒泰市| 南溪县| 申扎县| 怀宁县| 德庆县| 禄劝| 南安市| 无锡市| 漳平市| 涡阳县| 石狮市| 青田县| 常山县| 长丰县| 双城市| 延吉市| 临颍县| 五莲县| 潜山县| 南昌县| 阜南县| 广西| 广德县| 平安县| 壤塘县| 高青县|