2021SC@SDUSC
对于不需要在搜索反向索引时用到,但在搜索结果处理时需要的位置、偏移量、附加数据(payLoad) 的字段,我们可以单独为该字段存储(文档id词项向量)的正向索引。
package com.study.lucene.indexdetail;
import java.io.File;
import java.io.IOException;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType;
import org.apache.lucene.index.IndexOptions;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import com.study.lucene.ikanalyzer.Integrated.IKAnalyzer4Lucene7;
public class IndexTermVectorsDemo {
public static void main(String[] args) {
// 创建使用的分词器
Analyzer analyzer = new IKAnalyzer4Lucene7(true);
// 索引配置对象
IndexWriterConfig config = new IndexWriterConfig(analyzer);
try ( // 索引存放到文件系统中
Directory directory = FSDirectory
.open((new File("f:/test/indextest")).toPath());
// 创建索引写对象
IndexWriter writer = new IndexWriter(directory, config);) {
// 准备document
Document doc = new Document();
// 字段content
String name = "content";
String value = "张三说的确实在理";
FieldType type = new FieldType();
// 设置是否存储该字段
type.setStored(true); // 请试试不存储的结果
// 设置是否对该字段分词
type.setTokenized(true); // 请试试不分词的结果
// 设置该字段的索引选项
type.setIndexOptions(IndexOptions.DOCS); // 反向索引中只保存词项
// 设置为该字段保存词项向量
type.setStoreTermVectors(true);
type.setStoreTermVectorPositions(true);
type.setStoreTermVectorOffsets(true);
type.setStoreTermVectorPayloads(true);
type.freeze(); // 使不可更改
Field field = new Field(name, value, type);
// 添加字段
doc.add(field);
// 加入到索引中
writer.addDocument(doc);
} catch (IOException e) {
e.printStackTrace();
}
}
}
我们往往需要对搜索的结果支持按不同的字段进行排序,如商品搜索结果按价格排序、按销量排序等。以及对搜索结果进行按某字段分组统计,如按品牌统计。
存储的文档数据中(文档是行式存储) 就得把搜到的所有文档加载到内存中,来获取价格,再按价格排序。 如果搜到的文档列表量很大,存在 费内存 效率低的问题,所以 我们往往对结果列表是分页处理,并不需要把所有文档数据加载。
空间换时间:对这种需要排序、分组、聚合的字段,为其建立独立的文档->字段值的正向索引、列式存储。这样我们要加载搜中文档的这个字段的数据就快很多,耗内存少。
IndexableFieldType 中的 docValuesType方法 就是让你来为需要排序、分组、聚合的字段指定如何为该字段创建文档->字段值的正向索引的。