java

您所在的位置:网站首页 es错误覆盖字段 java

java

2024-06-25 01:41| 来源: 网络整理| 查看: 265

我有一个文档,其中包含许多字段(有些是嵌套的)在 elasticsearch 上建立了索引。例如:

{ "id" : 1, "username" : "...", "name" : "...", "surname" : "...", "address" : "...", "age": 42, ... "bookmarks" : [{...}, {...}], "tags" : [{...}, {...}] }

我的实体中只映射了一些文件(我不想映射整个文档):

@Document(indexName = "...", type = "...") public class User { @Id private int id; private String username; private String address; // getter/setter methods }

在服务类中,我想使用 ElasticsearchRepository 进行部分更新,没有映射实体中所有文档的字段:

public class UserServiceClass { @Autowired private UserElasticsearchRepository userElasticsearchRepository; public void updateAddress(int id, String updatedAddress) { User user = userElasticsearchRepository.findOne(id); user.setAddress(updatedAddress); userElasticsearchRepository.save(user); } }

但是save 方法会覆盖整个文档:

{ "id" : 1, "username" : "...", "address" : "..." }

ElasticsearchRepository 似乎不支持部分更新.所以我用了 ElasticsearchTemplate , 进行部分更新,例如:

public class UserServiceClass { @Autowired private UserElasticsearchRepository userElasticsearchRepository; @Autowired private ElasticsearchTemplate elasticsearchTemplate; public void updateAddress(int id, String updatedAddress) { User user = userElasticsearchRepository.findOne(id); if (user.getUsername().equals("system")) { return; } IndexRequest indexRequest = new IndexRequest(); indexRequest.source("address", updatedAddress); UpdateQuery updateQuery = new UpdateQueryBuilder().withId(user.getId()).withClass(User.class).withIndexRequest(indexRequest).build(); elasticsearchTemplate.update(updateQuery); } }

但拥有两个相似的引用(存储库和 ElasticsearchTemplate)似乎有点多余。

谁能建议我更好的解决方案?

最佳答案

您可以实现自己的自定义存储库,而不是同时将 ElasticsearchTemplate 和 UserElasticsearchRepository 注入(inject)您的 UserServiceClass并让您现有的 UserElasticsearchRepository 扩展它。

我假设您现有的 UserElasticsearchRepository 看起来像这样。

public interface UserElasticsearchRepository extends ElasticsearchRepository { .... }

您必须创建新的接口(interface)名称 UserElasticsearchRepositoryCustom。在此界面中,您可以列出您的自定义查询方法。

public interface UserElasticsearchRepositoryCustom { public void updateAddress(User user, String updatedAddress); }

然后通过创建一个名为 UserElasticsearchRepositoryImpl 的类来实现您的 UserElasticsearchRepositoryCustom,并在其中注入(inject) ElasticsearchTemplate 实现您的自定义方法

public class UserElasticsearchRepositoryImpl implements UserElasticsearchRepositoryCustom { @Autowired private ElasticsearchTemplate elasticsearchTemplate; @Override public void updateAddress(User user, String updatedAddress){ IndexRequest indexRequest = new IndexRequest(); indexRequest.source("address", updatedAddress); UpdateQuery updateQuery = new UpdateQueryBuilder().withId(user.getId()).withClass(User.class).withIndexRequest(indexRequest).build(); elasticsearchTemplate.update(updateQuery); } }

之后,只需使用 UserElasticsearchRepositoryCustom 扩展您的 UserElasticsearchRepository,它应该如下所示。

public interface UserElasticsearchRepository extends ElasticsearchRepository, UserElasticsearchRepositoryCustom { .... }

最后,您的服务代码应如下所示。

public class UserServiceClass { @Autowired private UserElasticsearchRepository userElasticsearchRepository; public void updateAddress(int id, String updatedAddress) { User user = userElasticsearchRepository.findOne(id); if (user.getUsername().equals("system")) { return; } userElasticsearchRepository.updateAddress(user,updatedAddress); } }

您还可以将用户查找逻辑也移至自定义存储库逻辑中,这样您就可以在方法中仅传递用户 ID 和地址。希望这对您有所帮助。

关于java - 使用 Spring Data Elasticsearch 存储库进行部分更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40742327/



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3