如何正确地解决"无法添加指向已存在类型的_parent字段,该字段不是父母"在应用启动

时间:2017-10-25 17:07:58

标签: spring-data-elasticsearch

我的Elasticsearch文档索引创建遇到问题,启动时失败" java.lang.IllegalArgumentException:无法添加指向已存在类型的_parent字段,不是父母"。我不确定这是由于版本升级还是b / c我是从一个全新的Elasticsearch服务器安装开始的。

显示我所看到的内容的示例:

// UserSearchResult.java
@Document(indexName = "hr_index", type = "user")
public class UserSearchResult implements Serializable {
    ...
    @Field(type=FieldType.keyword)
    @Parent(type="department")
    private String departmentCode;
    ...
}

// DepartmentSearchResult.java
@Document(indexName = "hr_index", type = "department")
public class DepartmentSearchResult implements Serializable {
    ...
}

当我启动我的应用程序时,我得到了那个例外。如果我检查ElasticSearch服务器,我会看到" hr_index"索引和"部门"映射,但"用户"没有创建映射。

如果我理解错误,那是因为"部门"正在创建,然后当Spring试图创建" user"与"部门"作为其父母,它并不喜欢这样,因为部门在创建之前并未被标记为父母。

  1. 是否有某种方式(通过注释?)将DepartmentSearchResult表示为以某种方式创建的父级?

  2. 或者,是否可以提示Spring Data Elasticsearch应该创建索引/映射的顺序?我已经看过其他一些帖子(Spring Data Elasticsearch Parent/Child Document Repositories / Test execution error),但是禁用自动创建,然后自己手动创建它(作为我的Spring代码库的一部分或应用程序的外部)似乎有点" un-Spring-y&# 34;给我?

  3. 或者,我应该采取其他方法吗?

  4. (这是一个使用Spring 4.2.1和Spring Data Release Train Gosling的Spring应用程序,我试图升级到使用Spring 5.0.0和Spring Data Release Train Kay。作为我从一个新的Elasticsearch安装开始,所以我不确定这个错误是来自升级还是只是b / c安装是干净的。)

1 个答案:

答案 0 :(得分:1)

在SD ES中,与亲子关系相关的问题目前尚未得到很好的发展。 问题很可能是由于您使用的是Elasticsearch的全新安装。在更新之前,问题没有出现,因为已经创建了映射。对于该解决方案,您可以使用elasticsearchTemplate(它是SD ES的一部分)和ApplicationListener。这很简单。只需3个步骤。

在ES中删除索引(只需要一次):

curl -XDELETE [ES_IP]:9200/hr_index

告诉SD ES不要自动创建索引和映射

// UserSearchResult.java
@Document(indexName = "hr_index", type = "user", createIndex = false)
public class UserSearchResult implements Serializable {
    ...
    @Field(type=FieldType.keyword)
    @Parent(type="department")
    private String departmentCode;
    ...
}

// DepartmentSearchResult.java
@Document(indexName = "hr_index", type = "department", createIndex = false)
public class DepartmentSearchResult implements Serializable {
    ...
}

添加ApplicationListener:

@Component
public class ApplicationStartupListener implements ApplicationListener<ContextRefreshedEvent> {

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    //Mapping for child must be created only if mapping for parents doesn't exist
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        elasticsearchTemplate.createIndex(DepartmentSearchResult.class);
        try {
            elasticsearchTemplate.getMapping(DepartmentSearchResult.class);
        } catch (ElasticsearchException e) {
            elasticsearchTemplate.putMapping(UserSearchResult.class);
            elasticsearchTemplate.putMapping(DepartmentSearchResult.class);
        }
    }
}

P.S。除其他事项外,值得注意的是,随着ES 5.6的发布,a process for removing types began。这不可避免地需要消除亲子关系。在SD ES的下一个版本中,我们将提供使用联接的机会。使用亲子关系不太可能得到改善