使用ElasticsearchRepository和RestHighLevelClient的saveAll(list)方法时出错。

huangapple go评论89阅读模式
英文:

Error using method saveAll(list) of ElasticsearchRepository and RestHighLevelClient

问题

我使用了 org.elasticsearch:elasticsearch 版本 6.8,并且为了连接使用了 TransportClient。然后,我决定升级到版本 7.6,由于 TransportClient 已被弃用,我不得不使用 RestHighLevelClient 进行与 Elasticsearch 的连接。我在 springframework 中使用存储弹性数据的 repository。但是现在我的 repository 不再正常工作。我的 repository 继承自 ElasticsearchRepository 接口,我使用标准的 saveAll 方法。

我有一个 MyPostgresModel 对象的列表,我需要将它保存到 Elasticsearch 中。为了快速完成,我使用了 @Transactional,并且使用带有 Iterable 参数的 saveAll 方法。MyPostgresModel 有一个 toDocument 方法,用于返回 MyElasticModel 对象。

以下代码有效:

myElasticRepository.save(users.get(0).toDocument());

但以下代码无效:

myElasticRepository.saveAll(() -> users.stream().map(MyPostgresModel::toDocument).iterator());

我不知道为什么会出问题。为什么会这样?这还返回了“type is missing;7930: type is missing;7931:..”错误。调试器告诉我 Elasticsearch 返回了“400 Bad Request”状态 - 数据验证未通过。

在我使用 TransportClient 之前,一切都正常。而且在所有情况下,TransportClient 和 RestHighLevelClient 都使用共同的 ElasticsearchOperations 接口...

我使用以下配置类进行连接:

@Slf4j
@Configuration
@EnableElasticsearchRepositories(basePackages = "com.project.elastic.repository")
public class ElasticConfig extends AbstractElasticsearchConfiguration {

    @Value("${spring.data.elastic.url}")
    private String url;

    @Override
    public RestHighLevelClient elasticsearchClient() {
        return RestClients.create(ClientConfiguration.create(url)).rest();
    }
}

以下是我的弹性模型示例:

@Data
@Document(indexName = "user", type = "_doc", createIndex = false)
public class ElasticUser {

    @Id
    private final String id;
    private final String address;
    private final String firstName;
    private final String lastName;
    private final List<String> phones;
    private final String gender;

    public ElasticUser(
            @NonNull String id,
            @NonNull String address,
            @NonNull String firstName,
            @NonNull String lastName,
            @NonNull List<String> phones,
            @Nullable String gender
    ) {
        this.id = id;
        this.address = address;
        this.firstName = firstName;
        this.lastName = lastName;
        this.phones = phones;
        this.gender = gender;
    }
}

服务方法:

@Transactional
public void saveUsers(@NonNull List<PostgresUser> users) {
//        myElasticRepository.save(users.get(0).toDocument());
    myElasticRepository.saveAll(() -> users.stream().map(PostgresUser::toDocument).iterator());
}
英文:

I used org.elasticsearch:elasticsearch version 6.8 and for connectivity I used TransportClient. I then decided to upgrade to version 7.6 and since TransportClient is Deprecated, I had to use the connection to elastic via the RestHighLevelClient. I'm using a repository to work with an elastic data in springframework. But now I don't have elastic data storage through a repository working. My repository is inherited from the ElasticsearchRepository interface. I use the standard saveAll method.

I have a list of MyPostgresModel and I need to save that into Elastic. I want to do quickly that's why I use @Transactional and use saveAll method with Iterable. MyPostgresModel has toDocument method to return MyElasticModel object.

This is works: myElasticRepository.save(users.get(0).toDocument());
And this isn't works: myElasticRepository.saveAll(() -&gt; users.stream().map(MyPostgresModel::toDocument).iterator());

I have no idea. Why not? That also returns "type is missing;7930: type is missing;7931:.." error. And the debuger tells me that elastic responses "400 Bad Request" status - data validation is not going.

Before I used the TransportClient everything was OK and after all TransportClient and RestHighLevelClient use a common ElasticsearchOperations interface...

I use the following config class for connection:

@Slf4j
@Configuration
@EnableElasticsearchRepositories(basePackages = &quot;com.project.elastic.repository&quot;)
public class ElasticConfig extends AbstractElasticsearchConfiguration {

    @Value(&quot;${spring.data.elastic.url}&quot;)
    private String url;

    @Override
    public RestHighLevelClient elasticsearchClient() {
        return RestClients.create(ClientConfiguration.create(url)).rest();
    }
}

Here is the example of my elastic model:

@Data
@Document(indexName = &quot;user&quot;, type = &quot;_doc&quot;, createIndex = false)
public class ElasticUser {

    @Id
    private final String id;
    private final String address;
    private final String firstName;
    private final String lastName;
    private final List&lt;String&gt; phones;
    private final String gender;

    public ElasticUser(
            @NonNull String id,
            @NonNull String address,
            @NonNull String firstName,
            @NonNull String lastName,
            @NonNull List&lt;String&gt; phones,
            @Nullable String gender
    ) {
        this.id = id;
        this.address = address;
        this.firstName = firstName;
        this.lastName = lastName;
        this.phones = phones;
        this.gender = gender;
    }
}

Service method:

    @Transactional
    public void saveUsers(@NonNull List&lt;PostgresUser&gt; users) {
//        myElasticRepository.save(users.get(0).toDocument());
        myElasticRepository.saveAll(() -&gt; users.stream().map(PostgresUser::toDocument).iterator());
    }

答案1

得分: 1

问题出在 Elasticsearch 版本上。我使用的客户端是 7.6.2,而我的 Elasticsearch 是 6.8.6。

英文:

The problem was with elasticsearch version. I used client with 7.6.2 and my elastic was 6.8.6.

huangapple
  • 本文由 发表于 2020年4月6日 15:07:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/61054593.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定