有多种方式可以通过注解实现不索引某个字段。以下是几种常用的方法,我会从最推荐的方式开始介绍。
方法一:使用 @Field
注解的 index
属性(最常用、最标准)
这是 Spring Data Elasticsearch 官方推荐的方式,通过设置 index = false
来明确禁止索引该字段。
语法:
@Field(type = FieldType.Text, index = false)
private String secretInfo;
示例:
public class WebMtoPost {
@Id
private Long id;
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String title; // 这个字段会被索引,可以搜索
@Field(type = FieldType.Text, index = false)
private String internalRemark; // 这个字段不会被索引,无法被搜索
// 其他字段...
}
效果:
internalRemark
字段会存储在_source
中(查询结果中可以看到它的值)- 但 无法 通过任何搜索条件(如
match
,term
查询)来匹配这个字段的内容 - 相当于在 Elasticsearch 映射中设置了
"index": false
方法二:使用 @Transient
注解(不推荐用于此目的)
@Transient
注解的意思是"瞬态的",它会告诉 Spring Data Elasticsearch 完全忽略这个字段。
语法:
import org.springframework.data.annotation.Transient;
@Transient
private String temporaryData;
示例:
public class WebMtoPost {
@Id
private Long id;
private String title;
@Transient
private String calculatedField; // 这个字段既不会被索引,也不会被存储
}
效果:
- 该字段 不会出现在 Elasticsearch 文档中
- 既不能搜索,在查询结果中也看不到这个字段
- 注意: 这通常用于临时计算字段或不想持久化的字段,如果只是想"不索引但保留存储",请使用方法一。
方法三:使用 @ReadOnlyProperty
注解(Spring Data 通用注解)
这个注解表示该字段是只读的,通常也会导致不被索引。
语法:
import org.springframework.data.annotation.ReadOnlyProperty;
@ReadOnlyProperty
private String readOnlyField;
方法对比总结
方法 | 注解 | 效果 | 适用场景 |
---|---|---|---|
推荐 | @Field(index = false) |
字段被存储,但不被索引 | 需要保留字段值但不希望被搜索(如备注、内部信息) |
不推荐 | @Transient |
字段不被存储也不被索引 | 临时计算字段、不想持久化的数据 |
可选 | @ReadOnlyProperty |
通常不被索引 | 只读字段 |
完整示例:在 WebMtoPost
中的应用
@Document(indexName = "mto_post")
public class WebMtoPost {
@Id
private Long id;
// 可搜索的字段
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String title;
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String content;
// 不索引但存储的字段(推荐方式)
@Field(type = FieldType.Text, index = false)
private String internalNotes; // 内部编辑备注
@Field(type = FieldType.Text, index = false)
private String auditComments; // 审核意见
// 不被索引且不被存储的字段
@Transient
private String wordCountInfo; // 临时统计的字数信息
// 可搜索的关键字字段
@Field(type = FieldType.Keyword)
private String status;
// 其他正常字段...
@Field(type = FieldType.Date)
private Date createTime;
// getter/setter 省略...
}
验证方法
创建索引后,你可以通过以下方式验证字段是否被正确设置:
-
查看索引映射:
GET /mto_post/_mapping
-
在返回的映射中,你会看到类似这样的结构:
{ "mto_post": { "mappings": { "properties": { "title": { "type": "text", "analyzer": "ik_max_word" }, "internalNotes": { "type": "text", "index": false // 这里显示 index: false } // ... 其他字段 } } } }
总结
对于"不索引但需要存储"的需求,强烈推荐使用:
@Field(index = false)
这是最语义化、最符合 Elasticsearch 设计意图的方式。