当修改的字段不总是相同时,如何更新 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)` 为您所做的)。
  • 首先获取实体,手动合并它(您可以轻松地为此创建一个基于反射的助手),然后更新它。