zoukankan      html  css  js  c++  java
  • mongo的$push与$setOnInsert冲突解决

    mongo的$push与$setOnInsert冲突解决

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

    示例

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

    满足这个需求使用$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无论文档是否存在都会做出添加操作,而$setOnInsert有可能会插入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无论文档是否存在都会做出添加操作(存在则直接添加,不存在会创建同名数组字段后添加),而$setOnInsert在文档不存在的时候才会插入相应字段,所以不存在时插入的文档是刚好完整的,而存在时更新只会添加一个year字段的元素。

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

  • 相关阅读:
    物理分页和逻辑分页扫盲
    JAVA集合操作的利器:CollectionUtils
    关于MYSQL表记录字段换行符回车符处理
    JSONObject依赖包
    Spring Mvc中@ResponseBody中文乱码解决,以及修改返回的Content-Type
    Python运行出错情况
    Python编码相关理解
    Python访问Access数据库
    Python
    android开发(1)
  • 原文地址:https://www.cnblogs.com/lymmurrain/p/15795997.html
Copyright © 2011-2022 走看看