Spring 数据 Elasticsearch 不会从注解隐式创建映射
Spring Data Elasticsearch doesn't implicitly create mapping from annotations
我正在尝试使用 Spring Data Elasticsearch 4.0.1,并试图弄清楚 Elasticsearch 映射是如何以及何时由 Spring 创建的,或者它们是否由 Spring.
如果我有这样的实体:
@Document(indexName = "companies")
public class CompanyEntity {
@Id
private final String id;
@MultiField(
mainField = @Field(type = Text),
otherFields = {
@InnerField(suffix = "raw", type = Keyword)
}
)
private final String companyName;
@PersistenceConstructor
public CompanyEntity(String id, String companyName) {
this.id = id;
this.companyName = companyName;
}
public String getId() {
return id;
}
public String getCompanyName() {
return companyName;
}
}
我的印象是 Spring 会隐式地为此索引创建映射,但我似乎弄错了。 Elasticsearch 仍会为此索引创建映射。
{
"companies": {
"mappings": {
"properties": {
"_class": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"companyName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"id": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
从上面可以清楚地看出,InnerField 注释中的后缀没有使用,ignore_above 值也没有使用,因为它默认为 -1,如果尝试设置 Elasticsearch 将完全删除该字段ignore_above 到 -1。
我能够获得上述注释的映射的唯一方法是自己显式设置映射。
@Autowired private ElasticsearchOperations operations;
Document mapping = operations.indexOps(CompanyEntity.class).createMapping();
operations.indexOps(CompanyEntity.class).putMapping(mapping);
这会产生预期的映射:
{
"companies": {
"mappings": {
"properties": {
"_class": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"companyName": {
"type": "text",
"fields": {
"raw": {
"type": "keyword"
}
}
},
"id": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
这很好,但我觉得有点奇怪,因为我在官方 Spring Data Elasticsearch docs 中找不到这种方法的任何细节。而且 JavaDocs 有点缺乏任何细节。
这是从 Spring 数据将映射安装到 Elasticsearch 的正确方法吗?
如果您正在使用 ElasticsearchOperations
进行工作,那么这就是创建映射的正确方法。在 4.1 版本中会有一个额外的方法
boolean putMapping(Class<?> clazz)
它结合了创建和写入映射两个步骤。
ElasticsearchOperations
和 IndexOperations
- 或更好的实现 - 是在 Spring 中对 Elasticsearch 的更底层访问 Elasticsearch - 创建索引,放置映射,写入实体等。这些都是基本操作。您可以完全控制执行哪些操作,但执行它们是您的责任。
在此之上构建的是存储库支持。如果定义一个存储库接口
interface CompanyRepository extends ElasticsearchRepository<CompanyEntity, String>{}
您将其注入您的 类
@Autowired CompanyRepository repository;
然后在应用程序启动时 Spring Data Elasticsearch 将创建此接口的实现,并将检查由实体的 @Document
注释定义的索引是否存在。如果不是,它将创建索引并写入映射 - @Document
注释有一个参数 createIndex
,默认情况下为 true。
因此,对于自动创建,您必须使用存储库,存储库支持还利用 ElasticsearchOperations
来提供诸如从方法名称派生查询、分页支持等功能。
我正在尝试使用 Spring Data Elasticsearch 4.0.1,并试图弄清楚 Elasticsearch 映射是如何以及何时由 Spring 创建的,或者它们是否由 Spring.
如果我有这样的实体:
@Document(indexName = "companies")
public class CompanyEntity {
@Id
private final String id;
@MultiField(
mainField = @Field(type = Text),
otherFields = {
@InnerField(suffix = "raw", type = Keyword)
}
)
private final String companyName;
@PersistenceConstructor
public CompanyEntity(String id, String companyName) {
this.id = id;
this.companyName = companyName;
}
public String getId() {
return id;
}
public String getCompanyName() {
return companyName;
}
}
我的印象是 Spring 会隐式地为此索引创建映射,但我似乎弄错了。 Elasticsearch 仍会为此索引创建映射。
{
"companies": {
"mappings": {
"properties": {
"_class": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"companyName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"id": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
从上面可以清楚地看出,InnerField 注释中的后缀没有使用,ignore_above 值也没有使用,因为它默认为 -1,如果尝试设置 Elasticsearch 将完全删除该字段ignore_above 到 -1。
我能够获得上述注释的映射的唯一方法是自己显式设置映射。
@Autowired private ElasticsearchOperations operations;
Document mapping = operations.indexOps(CompanyEntity.class).createMapping();
operations.indexOps(CompanyEntity.class).putMapping(mapping);
这会产生预期的映射:
{
"companies": {
"mappings": {
"properties": {
"_class": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"companyName": {
"type": "text",
"fields": {
"raw": {
"type": "keyword"
}
}
},
"id": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
这很好,但我觉得有点奇怪,因为我在官方 Spring Data Elasticsearch docs 中找不到这种方法的任何细节。而且 JavaDocs 有点缺乏任何细节。
这是从 Spring 数据将映射安装到 Elasticsearch 的正确方法吗?
如果您正在使用 ElasticsearchOperations
进行工作,那么这就是创建映射的正确方法。在 4.1 版本中会有一个额外的方法
boolean putMapping(Class<?> clazz)
它结合了创建和写入映射两个步骤。
ElasticsearchOperations
和 IndexOperations
- 或更好的实现 - 是在 Spring 中对 Elasticsearch 的更底层访问 Elasticsearch - 创建索引,放置映射,写入实体等。这些都是基本操作。您可以完全控制执行哪些操作,但执行它们是您的责任。
在此之上构建的是存储库支持。如果定义一个存储库接口
interface CompanyRepository extends ElasticsearchRepository<CompanyEntity, String>{}
您将其注入您的 类
@Autowired CompanyRepository repository;
然后在应用程序启动时 Spring Data Elasticsearch 将创建此接口的实现,并将检查由实体的 @Document
注释定义的索引是否存在。如果不是,它将创建索引并写入映射 - @Document
注释有一个参数 createIndex
,默认情况下为 true。
因此,对于自动创建,您必须使用存储库,存储库支持还利用 ElasticsearchOperations
来提供诸如从方法名称派生查询、分页支持等功能。