使用Elixir MongoDB驱动更新文档报错,求正确实现方式
解决Elixir MongoDB驱动更新文档的ArgumentError问题
这个错误我太熟悉了!你遇到的问题核心在于:MongoDB的更新操作(比如find_one_and_update)要求必须使用原子修改器,不能直接把普通字段(比如你的money)作为update参数的顶层键。
为什么会报错?
驱动里的Mongo.modifier_key/2函数会检查你传入的update参数,只有MongoDB官方支持的原子操作符(以$开头的,比如$set、$inc)才会被允许,普通字段名会直接触发这个ArgumentError。
正确的更新方式
下面给你几种常用的正确写法:
1. 更新指定字段(最常用):用$set原子修改器
如果你只想更新文档中的某个或某几个字段,用$set包裹要修改的键值对就可以了:
# 示例:更新指定文档的money字段 result = Mongo.find_one_and_update( your_collection, %{_id: target_document_id}, # 匹配要更新的文档 %{"$set": %{money: updated_money_amount}}, # 用$set包裹修改内容 return_document: :after # 可选:返回更新后的文档,默认返回更新前的 )
2. 其他常用原子修改器
根据你的业务需求,还可以用这些常用操作符:
$inc:给数值字段递增/递减,比如给money加50:%{"$inc": %{money: 50}}$push:往数组字段里添加新元素:%{"$push": %{transaction_history: %{amount: 100, date: DateTime.utc_now()}}}$unset:删除文档中的某个字段:%{"$unset": %{old_obsolete_field: ""}}
3. 替换整个文档
如果你需要完全替换掉原文档(而不是只更新部分字段),别用find_one_and_update,改用replace_one方法:
# 示例:替换整个文档 Mongo.replace_one( your_collection, %{_id: target_document_id}, %{_id: target_document_id, money: new_total, username: "updated_name", ...}, # 完整的新文档 upsert: false # 可选:如果文档不存在是否插入,默认false )
关键提醒
不管用哪种更新方式,只要是调用find_one_and_update这类**更新(而非替换)**的方法,update参数的顶层键必须是MongoDB的原子操作符(以$开头),绝对不能直接放普通字段名,这就是你触发错误的根本原因。
内容的提问来源于stack exchange,提问作者Denis Kuznetsov
相关产品推荐
相关产品推荐

