java - 当修改的字段并不总是相同时,如何更新 MongoDB 文档的字段?
问题描述
假设我有一个 Foo 类和一个将 API 公开给 CRUD Foos 的 jax-rs FooResource。
Foo 代表一个 MongoDB 文档。
在 FooResource 中,我会有这样的东西:
@PATCH
@Path("{id}")
public Response update(@PathParam("id") ObjectId id, Foo foo) {
return Response.ok(fooService.update(id, foo)).build();
}
问题是 json 中的 foo 对象将只包含已更改的字段,但我从来不知道它会是什么字段。
我使用带有 Panache 扩展的 Quarkus,我看到的唯一方法是从数据库中检索实体,然后检查我从 http 请求收到的 foo 对象中的每个字段,看看它是否为空,如果不是,在实体中设置新值,最后调用 update() 。
但是,如果我的课程有几十个领域,那将成为一场噩梦。这是一个如此常见的用例,我无法想象(或不想相信)这是做到这一点的唯一方法。
如果有一种方法可以将不完整的文档发送到 MongoDB,以便它只更改此文档中存在的字段,那将是完美的。但我没有找到办法做到这一点。不使用 quarkus(有或没有 panache),也没有使用 mongo API 的 java 驱动程序。
那么有没有更简单的方法来做到这一点?我更喜欢使用带有 Panache 扩展的 quarkus MongoDB 的解决方案,但没有 Panache 甚至直接使用 java 驱动程序 API 的解决方案也可以。
PS:从前端发送完整对象并替换整个文档对我来说不是一个选项。
谢谢。
解决方案
您可以使用该update(updateDocument, updateParams).where(query, params)
方法,它提供了更灵活的更新方法。
从文档指南的示例中:
// set the name of all living persons to 'Mortal'
long updated = Person.update("name", "Mortal").where("status", Status.Alive);
对于您的用例,查询部分位于_id
字段上,但您仍需要根据Foo
对象的字段存在动态构建更新部分。
正如您所说,当您使用类型化集合(集合绑定到 Java 类型而不是)时,没有办法轻松地做到这一点 Java 客户端Document
应该反映到数据库中(MongoDB 客户端如何知道 null 意味着有时不更新字段或将字段更新为 null)。
因此,对于这个用例,您可以:
- 使用所需的字段伪造更新
Document
(这是 ``update(updateDocument, updateParams).where(query, params)` 为你做的)。 - 首先获取实体,手动合并它(您可以轻松地为此创建基于反射的帮助器),然后更新它。
推荐阅读
- c++ - 关闭使用 CreateProcess() 打开的父进程后如何关闭消息框
- mysql - 在 MySQL 的一个 SELECT 语句中通过 > 100 个条件的最佳方法是什么?
- google-apps-script - 在使用 GAS 提交大型表单时,使用缓存服务来减少属性存储数据调用
- powershell - 将类型字符串转换为安全字符串
- ksqldb - 使用 group by 和 latest_by_offset 查询物化视图两次返回相同的键
- json - Postgresql group by query 转换 json 格式
- angular - 骆驼案例中的gRPC json数据
- macos - 为什么自制软件需要 /usr/local/share/man/man8 的权限
- javascript - 字符串没有在 javscript 中使用双引号打印?
- javascript - 如何在 react.js 中显示同一项目和不同日期的值的总和