不是为 Long 类型自动生成 ID,而是为 Spring Data Elasticsearch 中的 String 类型字段自动生成 ID

Not Auto-generating id for Long type but for String type field in Spring Data Elasticsearch

我正在使用 spring boot 版本 1.5.6.RELEASEspring-boot-starter-data-elasticsearch 相同版本的应用程序。

我有一个模型 Greeting 就像:

@Document(indexName = "index", type = "greetings")
public class Greeting implements Serializable{
    @Id
    private Long id;
    private String username;
    // Getter, Setter and constructor added here
}

我的控制器和服务 classes 对于以下没有类型 id 的情况是相同的。

当我发送以下 post 请求时:

curl -H "Content-Type: application/json" -X POST -d '{"username":"sunkuet02","message": "this is test"}' http://localhost:8080/api/greetings

它回复:

{"id":null,"username":"sunkuet02","message":"this is test"}

然后我更改了 Greeting class 将 id 的类型更改为字符串。

@Document(indexName = "index", type = "greetings")
public class Greeting implements Serializable{    
    @Id
    private String id;    
    private String username;
    // Getter, Setter and constructor added here
}

清理、构建并发送相同的 post 请求:

curl -H "Content-Type: application/json" -X POST -d '{"username":"sunkuet02","message": "this is test"}' http://localhost:8080/api/greetings

并得到以下响应:

{"id":"AV2cq2OXcuirs1TrVgG6","username":"sunkuet02","message":"this is test"}

场景是:当id字段的类型为Long时,它不会自动生成id,但如果类型为String 然后它会自动生成id。

我的问题是:

Spring Data Elasticsearch 在内部使用 _id 作为 Id 并且 _id 类型是字符串。当您在文档字段上使用@Id,并且您的数据类型是字符串时,spring 数据 ES 将其内部 _id 映射到您的字段。但是当你使用数字(Long、Integer 等)数据类型时,spring 数据 ES 无法将其自动生成的 _id 映射到你的 @Id 字段。如果你在 ES 上看到你的文档,你会看到你的文档 id 字段为空,_id get 的是自动生成的值。

你可以做的是,生成你自己的 id 并将其设置在你的文档中,然后 spring data ES 将在其内部 _id 中设置该字段的字符串值场地。您会看到您的文档 ID 字段包含您设置的值。

我会解释这部分:

What is the actual reason ? Does spring-data-elasticsarch always uses id field of type String ?

Elasticsearch 默认生成的 ID 长度为 20 个字符,URL-安全,Base64 编码的 GUID 字符串。

原因当然是性能 - 使用修改后的 Flake ID 可以增加索引数据时每秒的查找次数。一般来说 - Lucene 的基于段的性质促进 ID 在分配给段的方式上具有某种模式或具有一定的可预测性。

因此,如果您的应用程序并不真正关心 ID 的外观,最好坚持使用 Elsticsearch 提供的默认 ID。

更多信息在此 article 部分 使用自动 ID 或选择一个好的 ID