Spring Data Elasticsearch (4.x) - 在 _source 中使用 @Id 强制 id 字段
Spring Data Elasticsearch (4.x) - Using @Id forces id field in _source
总结
最近我们升级到 Spring Data Elasticsearch 4.x。这个主要版本的一部分意味着 Jackson 不再用于将我们的域对象转换为 json(改为使用 MappingElasticsearchConverter
)[1]。这意味着我们现在被迫向所有文档添加一个新的 id
字段。
以前我们有这样的域对象:
import org.springframework.data.annotation.Id;
public ESDocument {
@Id
private String id;
private String field1;
@JsonIgnore
public String getId() {
return id;
}
public String getField1() {
return field1;
}
这导致在 ES 中生成这样的文档:
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "d5bf7b5c-7a44-42f9-94d6-d59fe3988482",
"_score" : 1.0,
"_source" : {
"field1" : "blabla"
}
}
注意:
@JsonIgnore
注释用于确保我们不需要 在 _source
中有一个 id
字段。
- 我们自己设置文档 ID,它最终在
_id
。
问题
使用 Spring Data Elastic 4.x 不再遵守 @JsonIgnore
注释,这意味着我们现在被迫在 [=19= 中有一个 id
字段] 如下图:
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "d5bf7b5c-7a44-42f9-94d6-d59fe3988482",
"_score" : 1.0,
"_source" : {
"id": "d5bf7b5c-7a44-42f9-94d6-d59fe3988482",
"field1" : "blabla"
}
}
问题
- 是否不再可以省略文档标识符的重复项(即在
_id
和 id
字段中)?如果是这样怎么办? (请注意,我们已经尝试了 @org.springframework.data.annotation.Transient
,但它不起作用,因为 spring-data-elastic 然后认为我们的文档没有 ID)。
- 我们之前在
_source
中抑制 id
字段的方法是不正确的还是有问题的?
版本
java: 1.8.0_252
弹性搜索:7.6.2
spring-引导:2.3.1.RELEASE
spring-数据弹性:4.0.1.RELEASE
参考资料
[1] - https://spring.io/blog/2020/05/27/what-s-new-in-spring-data-elasticsearch-4-0
问题一:
要从 _source 中省略 id 字段,您通常会使用 @Transient
注释,但如您所写,这不适用于 id 属性。 Spring 数据模块(不仅是 Spring Data Elasticsearch)忽略瞬态属性。
但是您可以为此使用 org.springframework.data.annotation.ReadOnlyProperty
注释:
@Id
@ReadOnlyProperty
private String id;
老实说,到现在为止我都不知道它存在,它也来自 Spring Data Commons,并在 [=53= 的 isWriteable()
方法中进行了检查] 当属性由 MappingElasticsearchConverter
.
写入时
问题二:
当然没有错,但正如您所发现的那样有问题。我们在存储的时候总是考虑整个entity,所以从来没有想过不写id。严格来说,没有必要,你是对的,因为我们总是在 _id 字段中与 _source 一起获取 id,所以我们可以很容易地把实体放回原处,但我们从来没有认为这是一个必要的功能。
注:
当您查看 ES 索引中的数据时,您会发现 MappingElasticsearchConverter
一个额外的 _source 字段名为 _class 被写入其中包含实体的名称 class(或定义的别名)。这允许映射泛型;了解更多信息 check the documentation - 以防万一你想知道这是从哪里来的。
总结
最近我们升级到 Spring Data Elasticsearch 4.x。这个主要版本的一部分意味着 Jackson 不再用于将我们的域对象转换为 json(改为使用 MappingElasticsearchConverter
)[1]。这意味着我们现在被迫向所有文档添加一个新的 id
字段。
以前我们有这样的域对象:
import org.springframework.data.annotation.Id;
public ESDocument {
@Id
private String id;
private String field1;
@JsonIgnore
public String getId() {
return id;
}
public String getField1() {
return field1;
}
这导致在 ES 中生成这样的文档:
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "d5bf7b5c-7a44-42f9-94d6-d59fe3988482",
"_score" : 1.0,
"_source" : {
"field1" : "blabla"
}
}
注意:
@JsonIgnore
注释用于确保我们不需要 在_source
中有一个id
字段。- 我们自己设置文档 ID,它最终在
_id
。
问题
使用 Spring Data Elastic 4.x 不再遵守 @JsonIgnore
注释,这意味着我们现在被迫在 [=19= 中有一个 id
字段] 如下图:
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "d5bf7b5c-7a44-42f9-94d6-d59fe3988482",
"_score" : 1.0,
"_source" : {
"id": "d5bf7b5c-7a44-42f9-94d6-d59fe3988482",
"field1" : "blabla"
}
}
问题
- 是否不再可以省略文档标识符的重复项(即在
_id
和id
字段中)?如果是这样怎么办? (请注意,我们已经尝试了@org.springframework.data.annotation.Transient
,但它不起作用,因为 spring-data-elastic 然后认为我们的文档没有 ID)。 - 我们之前在
_source
中抑制id
字段的方法是不正确的还是有问题的?
版本
java: 1.8.0_252
弹性搜索:7.6.2
spring-引导:2.3.1.RELEASE
spring-数据弹性:4.0.1.RELEASE
参考资料
[1] - https://spring.io/blog/2020/05/27/what-s-new-in-spring-data-elasticsearch-4-0
问题一:
要从 _source 中省略 id 字段,您通常会使用 @Transient
注释,但如您所写,这不适用于 id 属性。 Spring 数据模块(不仅是 Spring Data Elasticsearch)忽略瞬态属性。
但是您可以为此使用 org.springframework.data.annotation.ReadOnlyProperty
注释:
@Id
@ReadOnlyProperty
private String id;
老实说,到现在为止我都不知道它存在,它也来自 Spring Data Commons,并在 [=53= 的 isWriteable()
方法中进行了检查] 当属性由 MappingElasticsearchConverter
.
问题二:
当然没有错,但正如您所发现的那样有问题。我们在存储的时候总是考虑整个entity,所以从来没有想过不写id。严格来说,没有必要,你是对的,因为我们总是在 _id 字段中与 _source 一起获取 id,所以我们可以很容易地把实体放回原处,但我们从来没有认为这是一个必要的功能。
注:
当您查看 ES 索引中的数据时,您会发现 MappingElasticsearchConverter
一个额外的 _source 字段名为 _class 被写入其中包含实体的名称 class(或定义的别名)。这允许映射泛型;了解更多信息 check the documentation - 以防万一你想知道这是从哪里来的。