注:本文基于Lucene 8.2.0 版本。
回忆一下之前文章中创建字段(Field)的一些代码片段:
// 片段1 Field pathField = new StringField("path", file.toString(),Field.Store.YES); // 片段2 FieldType fieldType = new FieldType(); fieldType.setStored(true); fieldType.setStoreTermVectors(true); fieldType.setStoreTermVectorOffsets(true); fieldType.setStoreTermVectorPositions(true); fieldType.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS); Field field = new Field("content", sentence, fieldType);
在创建Field的时候,第一个参数是字段名,第二个是字段值,第三个就是字段属性了。字段的属性决定了字段如何Analyze,以及Analyze之后存储哪些信息,进而决定了以后我们可以使用哪些方式进行检索。本文就来介绍字段以及它的的一些常用属性。
Field对应的类是org.apache.lucene.document.Field,该类实现了org.apache.lucene.document.IndexableField接口,代表用于indexing的一个字段。Field类比较底层一些,所以Lucene实现了许多Field子类,用于不同的场景,比如下图是IDEA分析出来的Field的子类:
如果有某个子类能满足我们的场景,那推荐使用子类。在介绍常用子类之前,需要了解一下字段的三大类属性:
这些属性就是由之前文章中介绍的org.apache.lucene.index.IndexOptions枚举类定义的:
Field的各个子类就是实现了对不同类型字段的存储,同时选择了不同的字段属性,这里列举几个常用的:
所以,对于Field及其子类我们需要注意以下两点:
org.apache.lucene.document.FieldType类实现了org.apache.lucene.index.IndexableFieldType接口,用于描述字段的属性。之前的文章中有使用过该类来自定义字段属性的代码,这里再贴一下相关的代码片段:
FieldType fieldType = new FieldType(); fieldType.setStored(true); fieldType.setStoreTermVectors(true); fieldType.setStoreTermVectorOffsets(true); fieldType.setStoreTermVectorPositions(true); fieldType.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS); Field field = new Field("content", sentence, fieldType);
该类定义了一些成员变量,这些成员变量就是字段的一些属性,这里列一下代码中的成员变量:
private boolean stored; private boolean tokenized = true; private boolean storeTermVectors; private boolean storeTermVectorOffsets; private boolean storeTermVectorPositions; private boolean storeTermVectorPayloads; private boolean omitNorms; private IndexOptions indexOptions = IndexOptions.NONE; private boolean frozen; private DocValuesType docValuesType = DocValuesType.NONE; private int dataDimensionCount; private int indexDimensionCount; private int dimensionNumBytes; private Map<String, String> attributes;
大部分属性含义已经比较清楚了,这里再简单介绍一下其含义:
本文内容比较杂乱,但其实对于我们使用(包括ES、Solr等基于Lucene的软件)而言,只需要知道我们检索一个字段的时候可以控制保存哪些信息,以及这些信息在什么场景下使用,能带来什么好处,又会产生什么弊端即可。举个例子:比如我们在设计字段的时候,如果一个字段不会用来排序,也不会做聚集,那就没有必要生成DocValue,既能节省磁盘空间,又能提高写入速度。另外对于norm信息,如果你的场景只关注是否包含,那无需保存norm信息,但如果也关注相似度评分,并且文本长短是一个需要考虑的因素,那就应该保存norm信息。
本文来源:NYC's Blog,转载请注明出处!
来源地址:https://niyanchun.com/lucene-learning-6.html
最新内容
© 2016 - 2024 chengxuzhixin.com All Rights Reserved.