如何正确解决“无法添加指向已存在类型的 _parent 字段,该字段还不是父类型"的问题在应用程序启动时 [英] How to correctly address "can't add a _parent field that points to an already existing type, that isn't already a parent" on app startup

查看:35
本文介绍了如何正确解决“无法添加指向已存在类型的 _parent 字段,该字段还不是父类型"的问题在应用程序启动时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm running into a problem with my Elasticsearch Document index creation failing on startup with "java.lang.IllegalArgumentException: can't add a _parent field that points to an already existing type, that isn't already a parent". I'm not sure if this is due to a version upgrade or b/c I am starting with a brand new Elasticsearch server install.

显示我所看到的人为示例:

Contrived example that shows what I'm seeing:

// 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"索引和部门"映射,但未创建用户"映射.

When I start my application I get that exception. If I check the ElasticSearch server, I see the "hr_index" index and the "department" mapping, but the "user" mapping is not created.

如果我理解错误,那是因为正在创建部门",然后当 Spring 尝试使用部门"作为其父级创建用户"时,它不喜欢那样,因为部门之前没有被标记为创建时的父级.

If I understand the error, it's because "department" is being created and then when Spring tries to create "user" with "department" as its parent, it doesn't like that, since department wasn't previously marked as a parent when it was created.

  1. 当以某种方式创建时,是否有某种方法(通过注释?)将 DepartmentSearchResult 表示为父项?

  1. Is there some way (via annotation?) to denote DepartmentSearchResult as being a parent when it's created somehow?

或者,是否可以向 Spring Data Elasticsearch 提示它应该以什么顺序创建索引/映射?我看过其他一些帖子(Spring Data Elasticsearch Parent/子文档存储库/测试执行错误)但禁用自动创建然后自己手动创建它(作为我的 Spring 代码库的一部分或应用程序的外部)对我来说似乎有点非 Spring-y"?

Or, is it possible to give a hint to Spring Data Elasticsearch as to what order it should create the indices/mappings? I have seen some other posts (Spring Data Elasticsearch Parent/Child Document Repositories / Test execution error) but disabling auto creation and then manually creating it myself (either as part of my Spring codebase or external to the app) seems kind of "un-Spring-y" to me?

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

Or, is there some other approach I should be taking?

(这是一个一直在使用 Spring 4.2.1 和 Spring Data Release Train Gosling 的工作 Spring 应用程序,我正在尝试升级以使用 Spring 5.0.0 和 Spring Data Release Train Kay.作为其中的一部分,我我从全新的 Elasticsearch 安装开始,所以我不确定这个错误是来自升级还是只是 b/c 安装是干净的).

(This is a working Spring application that had been using Spring 4.2.1 and Spring Data Release Train Gosling, that I'm attempting to upgrade to use Spring 5.0.0 and Spring Data Release Train Kay. As part of this I am starting with a fresh Elasticsearch install, and so I'm not sure if this error is coming from the upgrade or just b/c the install is clean).

推荐答案

在 SD ES 中,与亲子关系相关的问题现在确实很不完善.问题很可能是由于您使用的是全新安装的 Elasticsearch.在更新之前,问题没有出现,因为映射已经创建.对于解决方案,您可以使用作为 SD ES 一部分的 elasticsearchTemplate 和 ApplicationListener.这很简单.只需3步.

In the SD ES, issues related to the parent-child relationship at now really poorly developed. The problem is most likely due to the fact that you are using a clean installation of Elasticsearch. Before the update, the problem did not arise, because mappings have already been created. For the solution, you can use elasticsearchTemplate, which is part of SD ES, and ApplicationListener. It's simple. Just 3 steps.

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

Drop index in ES (it only needs one time):

curl -XDELETE [ES_IP]:9200/hr_index

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

Tell SD ES not to create indices and mappings automatically

// 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 {
    ...
}

添加一个应用程序监听器:

Add a 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);
        }
    }
}

PS 值得一提的是,随着 ES 5.6 的发布,开始删除类型的过程.这不可避免地需要消除亲子关系.在 SD ES 的下一个版本中,我们将提供使用联接的机会.处理亲子关系的可能性不大

P.S. Among other things, it is worth paying attention to the fact that with the release of ES 5.6, a process for removing types began. This inevitably entails the removal of the parent-child relationship. In one of the next releases of the SD ES, we will provide the opportunity to work with joins. Working with parent-child relationships is unlikely to be improved

这篇关于如何正确解决“无法添加指向已存在类型的 _parent 字段,该字段还不是父类型"的问题在应用程序启动时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆