如何在MongoDB中更新所有文档字段,除了特定的字段?

8
我给出一个简单的模型:

public class UserDocument
{
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; set; }

    public string DisplayName { get; set; }

    public List<string> Friends { get; set; }
}

我正在使用最新的C#驱动程序,它具有使用C#对象替换文档并自动更新其所有字段的功能。问题是我想要更新除“用户朋友”之外的所有字段,因为“用户朋友”是包含与其他文档关系的对象字段。当然,我可以手动更新要更新的每个字段,这里只有两个。

但是这个示例很简单,只是为了说明我的观点。实际上,字段要多得多,更新每个字段将更加困难。那将需要使用Set运算符的每个字段都需要一行代码。此外,新添加的字段必须以相同的方式支持,而不是自动更新。

有没有办法通过指定排除字段的列表来自动更新所有字段?


我曾遇到一个类似的案例,有着与你所描述的相似的需求...你能分享一下你是如何解决它的吗? - Yohan
我记不得除了我的问题或@i3arnon的答案中提到的方法之外还有什么其他解决方案,否则我会在这里发布的。 - Ceco
2个回答

9

使用提供的构建器无法实现“黑名单”更新,该更新仅排除特定字段。

您可以查询旧文档,将这些字段的旧值复制到新实例中,然后在数据库中完全替换它。

您还可以通过使用反射迭代字段来生成此类更新命令。

但是MongoDB驱动程序没有内置此类查询


1

我使用Javascript/NodeJS想出了一种在MongoDB中实现此操作的方法,但也许这个逻辑可以翻译成C#?

我希望能够更新所有字段,而不必明确地列出它们(除了一个字段之外)。

尝试更新所有文档字段:

await examCollection.findOneAndUpdate(
  {_id: new ObjectID(this.examId)},
  {$set: this.data}
)

除了这个this.data恰好也有_id,我不想更新它。事实上,它给了我一个错误,因为_id是不可变的。

因此,为了解决问题,我最终“删除”了对象上我不想更新的所有字段(即_id)。

成功更新所有未指定的文档字段:

// (1) specify fields that I don't want updated (aka get rid of them from object) (similar option in C#?)
delete this.data._id 
//delete this.data.anotherField
//delete this.data.anotherField2
//delete this.data.anotherField3
    
// (2) update MongoDB document
await examCollection.findOneAndUpdate(
  {_id: new ObjectID(this.examId)},
  {$set: this.data}
)

这比明确说明我想要更新的所有字段要容易得多,因为有很多,并且可能会在将来更改(添加新字段,删除字段等)。希望这种策略可以帮助!请注意:实际上,我在另一个文件中早些时候进行了“字段指定”,而不是像示例中显示的那样立即进行更新,但效果相同。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接