Lucene系列(6)——字段及其属性

2021-11-26 From NYC's Blog By 倪彦春
注:本文基于Lucene 8.2.0 版本。
<p> 回忆一下之前文章创建字段(Field)的一些代码片段: p>
// 片段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);
<p>创建Field的时候,第一个参数是字段名,第二个是字段值,第三个就是字段属性了。字段的属性决定了字段如何Analyze,以及Analyze之后存储哪些信息,进而决定了以后我们可以使用哪些方式进行检索。本文就来介绍字段以及它的的一些常用属性。 p>

1. Field类

<p> Field对应的类是org.apache.lucene.document.Field,该类实现了org.apache.lucene.document.IndexableField接口,代表用于indexing的一个字段。Field类比较底层一些,所以Lucene实现了许多Field子类用于不同的场景,比如下图是IDEA分析出来的Field的子类p> <p> image-20190918223509632 p> <p> 如果有某个子类能满足我们的场景,那推荐使用子类。在介绍常用子类之前,需要了解一下字段的三大类属性: p> <p> 这些属性就是由之前文章介绍的org.apache.lucene.index.IndexOptions枚举类定义的: p>
  • NONE:不索引
  • DOCS:只索引字段,不保存词频等位置信息
  • DOCS_AND_FREQS:索引字段并保存词频信息,但不保存位置信息
  • DOCS_AND_FREQS_AND_POSITIONS:索引字段并保存词频及位置信息
  • DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS:索引字段并保存词频、位置、偏移量等信息
<p> Field的各个子类就是实现了对不同类型字段的存储,同时选择了不同的字段属性,这里列举几个常用的: p> <p> 所以,对于Field及其子类我们需要注意以下两点: p>
  1. 几乎所有的Field子类(除StoredField)都默认存储原始数据,如果需要存储原始数据,就要额外增加一个StoredField类型的字段,专门用于存储原始数据。注意该类也是Field的一个子类。当然也有一些子类的构造函数提供参数来控制是否存储原始数据,比如StringField,创建实例时可以通过传递Field.Store.YES参数存储原始数据
  2. Field子类使用场景和对应的属性都已经设置好了,如果子类不能满足我们的需求,就需要对字段属性进行定义,但子类的属性一般是不允许更改的,需要直接使用Field类,再配合FieldType类进行定义化。

2. FieldType类

<p> org.apache.lucene.document.FieldType类实现了org.apache.lucene.index.IndexableFieldType接口用于描述字段的属性。之前的文章中有使用过该类来自定义字段属性的代码,这里再贴一下相关的代码片段: p>
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);
<p> 该类定义了一些成员变量,这些成员变量就是字段的一些属性,这里列一下代码中的成员变量p>
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;
<p> 大部分属性含义已经比较清楚了,这里再简单介绍一下其含义: p> <p> 本文内容比较杂乱,但其实对于我们使用包括ES、Solr等基于Lucene软件)而言,只需要知道我们检索一个字段的时候可以控制保存哪些信息,以及这些信息在什么场景使用,能带来什么好处,又会产生什么弊端即可。举个例子:比如我们在设计字段的时候,如果一个字段不会用来排序,也不会做聚集,那就没有必要生成DocValue,既能节省磁盘空间,又能提高写入速度。另外对于norm信息,如果你的场景只关注是否包含,那无需保存norm信息,但如果也关注相似度评分,并且文本长短是一个需要考虑的因素,那就应该保存norm信息p>

本文来源:NYC's Blog,转载请注明出处!

来源地址:https://niyanchun.com/lucene-learning-6.html

发表感想

© 2016 - 2022 chengxuzhixin.com All Rights Reserved.

浙ICP备2021034854号-1    浙公网安备 33011002016107号