mongo的$push与$setOnInsert冲突解决

本文介绍了在MongoDB中如何解决$push和$setOnInsert操作冲突的问题。业务需求是在更新时,如果集合中不存在文档则插入,如果存在则向文档的数组字段添加元素。错误的示例代码会导致冲突,因为$push会始终尝试添加操作,而$setOnInsert在文档不存在时插入。正确的做法是将year字段单独处理,避免在doc中出现,以防止冲突。此外,还提到push与set操作也可能产生冲突,解决方法类似。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

mongo的push与push与pushsetOnInsert冲突解决

业务需求 update时集合中若不存在则插入文档,若存在则将该文档的一个数组字段添加一个元素。

示例

# 集合中一开始不存在name为1的文档,插入该文档
doc = {'name':1,'year':[2000]}
# 现在集合中有name为1的文档,则将year为2001添加到上面的文档中的year字段中
doc = {'name':1,'year':[2001]}

满足这个需求使用push,push,push,setOnInsert,upsert即可完成,但存在易错点。

以下代码使用pymongo

错误写法
col.update({'name': 1}, {
'$push': {'year': doc['year']},'$setOnInsert':doc}, upsert=True)

如果写成上面这样,会报如下错误

pymongo.errors.WriteError: Updating the path 'year' would create a conflict at 'year', full error: {'index': 0, 'code': 40, 'errmsg': "Updating the p
ath 'year' would create a conflict at 'year'"}

原因是push无论文档是否存在都会做出添加操作,而push无论文档是否存在都会做出添加操作,而pushsetOnInsert有可能会插入doc文档,文档中又有year字段,则会产生冲突。

正确使用

将year单独存一个变量放在push语句中,doc不能存在year键值对

doc = {'name':1,'year':[2001]}
year = doc.pop('year')
col.update({'name': 1}, {
'$push': {'year':year},'$setOnInsert':doc}, upsert=True)

由于push无论文档是否存在都会做出添加操作(存在则直接添加,不存在会创建同名数组字段后添加),而push无论文档是否存在都会做出添加操作(存在则直接添加,不存在会创建同名数组字段后添加),而pushsetOnInsert在文档不存在的时候才会插入相应字段,所以不存在时插入的文档是刚好完整的,而存在时更新只会添加一个year字段的元素。

push与push与pushset也会冲突,解决方法相似。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值