当修改的字段不总是相同时,如何更新 MongoDB 文档的字段?
how to update the fields of a MongoDB document when the modified fields are not always the same?
假设我有一个 Foo class 和一个向 CRUD Foos 公开 API 的 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()。
但如果我有一个包含几十个字段的 class,那将成为一场噩梦。
这是一个如此常见的用例,我无法想象(或不想相信)这是执行此操作的唯一方法。
如果有一种方法可以将不完整的文档发送到 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 类型而不是 Document
) null值字段应该反映到数据库中(MongoDB客户端怎么知道null表示有时不更新字段或将字段更新为null)。
因此对于此用例,您可以:
- 使用所需的字段创建更新
Document
(这就是 ``update(updateDocument, updateParams).where(query, params)` 为您所做的)。
- 首先获取实体,手动合并它(您可以轻松地为此创建一个基于反射的助手),然后更新它。
假设我有一个 Foo class 和一个向 CRUD Foos 公开 API 的 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()。
但如果我有一个包含几十个字段的 class,那将成为一场噩梦。 这是一个如此常见的用例,我无法想象(或不想相信)这是执行此操作的唯一方法。
如果有一种方法可以将不完整的文档发送到 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 类型而不是 Document
) null值字段应该反映到数据库中(MongoDB客户端怎么知道null表示有时不更新字段或将字段更新为null)。
因此对于此用例,您可以:
- 使用所需的字段创建更新
Document
(这就是 ``update(updateDocument, updateParams).where(query, params)` 为您所做的)。 - 首先获取实体,手动合并它(您可以轻松地为此创建一个基于反射的助手),然后更新它。