在mongo中,有一个命令非常的方便,就是upsert,顾名思义就是update+insert的作用

根据条件判断有无记录,有的话就更新记录,没有的话就插入一条记录

upsert的使用方法:

MongoDB shell version: 2.4.9
connecting to: test
> use date
switched to db date
> db.user.insert({"name":"user1", "age":12, "sex":"male"})
> db.user.insert({"name":"user2", "age":13, "sex":"male"})
> db.user.insert({"name":"user3", "age":14, "sex":"male"})
> db.user.find()
{ "_id" : ObjectId("54c75876662ee1617463f0a3"), "name" : "user1", "age" : 12, "sex" : "male" }
{ "_id" : ObjectId("54c75880662ee1617463f0a4"), "name" : "user2", "age" : 13, "sex" : "male" }
{ "_id" : ObjectId("54c7588d662ee1617463f0a5"), "name" : "user3", "age" : 14, "sex" : "male" }
> db.user.update({"name":"user1"}, {"$set":{"age":21}}, {"upsert":"true"})
> db.user.find()
{ "_id" : ObjectId("54c75876662ee1617463f0a3"), "name" : "user1", "age" : 21, "sex" : "male" }
{ "_id" : ObjectId("54c75880662ee1617463f0a4"), "name" : "user2", "age" : 13, "sex" : "male" }
{ "_id" : ObjectId("54c7588d662ee1617463f0a5"), "name" : "user3", "age" : 14, "sex" : "male" }
> db.user.update({"name":"user1"}, {"$set":{"age":21}, "$setOnInsert":{"sex":"female"}}, {"upsert":"true"})
> db.user.find()
{ "_id" : ObjectId("54c75876662ee1617463f0a3"), "name" : "user1", "age" : 21, "sex" : "male" }
{ "_id" : ObjectId("54c75880662ee1617463f0a4"), "name" : "user2", "age" : 13, "sex" : "male" }
{ "_id" : ObjectId("54c7588d662ee1617463f0a5"), "name" : "user3", "age" : 14, "sex" : "male" }
> db.user.update({"name":"user4"}, {"$set":{"age":21}, "$setOnInsert":{"sex":"female"}}, {"upsert":"true"})
> db.user.find()
{ "_id" : ObjectId("54c75876662ee1617463f0a3"), "name" : "user1", "age" : 21, "sex" : "male" }
{ "_id" : ObjectId("54c75880662ee1617463f0a4"), "name" : "user2", "age" : 13, "sex" : "male" }
{ "_id" : ObjectId("54c7588d662ee1617463f0a5"), "name" : "user3", "age" : 14, "sex" : "male" }
{ "_id" : ObjectId("54c75a07478a805237d087c3"), "name" : "user4", "age" : 21, "sex" : "female" }
>

上面的代码可以看出,$set搭配$setOnInsert使用就可以实现更新和插入时的一些事件了。

比如实现更新数据,如果一些需要更新的,就用$set设置,如果有些如创建日期这种字段,那么使用$setOnInsert更新

相当方便,如果想知道刚才执行的upsert是更新还是插入,使用如下的方法即可(如下代码在上面的代码数据基础之上)

> db.user.update({"name":"user4"}, {"$set":{"age":21}, "$setOnInsert":{"sex":"female"}}, {"upsert":"true"})
> db.runCommand('getlasterror')
{
"connectionId" : 35,
"updatedExisting" : true,
"n" : 1,
"syncMillis" : 0,
"writtenTo" : null,
"err" : null,
"ok" : 1
}
> db.user.update({"name":"user5"}, {"$set":{"age":21}, "$setOnInsert":{"sex":"female"}}, {"upsert":"true"})
> db.runCommand('getlasterror')
{
"connectionId" : 35,
"updatedExisting" : false,
"upserted" : ObjectId("54c75caa478a805237d087c4"),
"n" : 1,
"syncMillis" : 0,
"writtenTo" : null,
"err" : null,
"ok" : 1
}
>

上面的updatedExisting 就可以反馈刚才的状态,true为更新操作,false为插入操作

当upsert为插入操作还可以返回ObjectId呢,是不是很方便~

其实上面的操作都是在mongo中直接操作的,很多时候更新数据都是使用脚本,以python为例

代码还是稍微有点不同的

pymongo

#!/bin/env python
#encoding:utf-8
import os
import pymongo DATA_DIR = 'data' # 连接数据库
conn = pymongo.Connection('127.0.0.1', 27017)
#conn = pymongo.Connection('115.28.55.217', 27017)
db = conn.haha db.users.remove() # Insert & Save
db.users.insert({'name': 'user1', 'age': 16, 'index': 1})
db.users.insert({'name': 'user2', 'age': 17, 'index': 2})
db.users.insert({'name': 'user3', 'age': 18, 'index': 3})
db.users.save({'name': 'user4', 'age': 19, 'index': 4}) # Update
db.users.update({'name':'user1'}, {'$set': {'age': 20}})
json = {
'age':20
}
db.users.update({'name':'user2'}, {'$set': json}) # Upsert
db.users.update({'name':'user5'}, {'$set': {'age': 22}, '$setOnInsert': {'index':5}}, upsert=True) json = {
'age':36
}
name = 'user5'
db.users.update({'name':name}, {'$set': json, '$setOnInsert': {'index':5}}, upsert=True)

因为python中不认识true,所以使用True,并且为了代码的可读性,建议使用upsert=True

当然,pymongo中的返回信息也是有区别的。

并不是db.runCommand('getlasterror')而是db.command('getlasterror')

那么使用如下代码就可以获取刚才update的类型了

status = db.command('getlasterror')['updatedExisting']
print status

记录完成

MongoDB的upsert状态判断和pymongo使用方法的更多相关文章

  1. [代码笔记]VUE路由根据返回状态判断添加响应拦截器

    //返回状态判断(添加响应拦截器) Axios.interceptors.response.use( res => { //对响应数据做些事 if (res.data && !r ...

  2. SpringBoot29 登录逻辑、登录状态判断

    1 知识点扫盲 浏览器和服务器之间时通过session来确定连接状态的,浏览器第一次请求时服务端会自动生成一个session,并将这个sessionId传回给浏览器,浏览器将这个sessionId存放 ...

  3. SKU多维属性状态判断算法

    作者:周琪力,前端工程师,网络常用昵称「keelii」.在过去的4年里主要负责京东网站商品详情页的前端系统架构和开发,平时主要写 JavaScript 偶尔写点NodeJS,Python.琪力博客:  ...

  4. C# MVC 用户登录状态判断 【C#】list 去重(转载) js 日期格式转换(转载) C#日期转换(转载) Nullable<System.DateTime>日期格式转换 (转载) Asp.Net MVC中Action跳转(转载)

    C# MVC 用户登录状态判断   来源:https://www.cnblogs.com/cherryzhou/p/4978342.html 在Filters文件夹下添加一个类Authenticati ...

  5. 判断密码是否可见/判断登录的状态/判断在form表单中 定义rules规则验证(iview)

    一: 判断密码是否可见判断:type="visiblePassword ? 'text' : 'password'" 是否为false 或者 true 密码为输入框或者文本框点击眼 ...

  6. Python3中使用PyMongo的方法详解

    前言 本文主要给大家介绍的是关于在Python3使用PyMongo的方法,分享出来供大家参考学习,下面话不多说了,来一起看看详细介绍: MongoDB存储 在这里我们来看一下Python3下Mongo ...

  7. java基础知识回顾之java Thread类学习(十)--线程的状态以及转化使用的方法介绍

       线程的概述:         线程是程序的多个执行路径,执行调度的单位,依托于进程存在.线程不仅可以共享进程的内存,而且还拥有一个属于自己的内存空间,这段内存空间叫做线程栈,是建立线程的时候由系 ...

  8. 笔记:1.css样式,最前边加 @charset "utf-8";是为什么2.js判断各种浏览器的方法

    表明CSS文件的页面编码为UTF-8..如果这个CSS的文件编码也是UTF-8的话..那么在浏览器中看到的CSS文件的页面中中文的注释或者中文字体就可以正确显示为中文,如果CSS的文件编码和页面不一致 ...

  9. 在foreach的判断条件里执行方法会有效率问题吗?

    楼猪平时一有空就有看别人代码的习惯,从许多优秀规范的代码中学习到了很多简约高效的写法和画龙点睛的思想精华.但是有的时候也会觉得某些写法很值得玩味.比如刚看到一段代码,在foreach的条件判断里加了一 ...

随机推荐

  1. Mybatis如何SQL声明表名称参数

    insert into prefix_${table_name} (a, b, c) values (#{a}, #{b}, #{c}) ${} 它代表了直接使用字面(literal value) # ...

  2. LVM 命令集总结(转)

    PV 命令 下面的命令是在与物理卷相关的操作中最常用的命令: lsdev 列出ODM中的设备. chdev 修改设备的特征. mkdev 增加一个设备到系统中. chpv 修改物理卷的状态. lspv ...

  3. CSDN个人空间能再烂吗?

    CSDN空间你敢再烂么? 从CSDN博客跳转到CSDN个人空间的入口还算明显,可是想从个人空间跳转到博客,可真是众里寻他千百度.跳转接口怎么寻都寻不到.根本没有这个跳转的入口.唯一的途径仅仅能从写博文 ...

  4. Caused by: org.springframework.beans.NotWritablePropertyException

    1.错误叙述性说明 usage: java org.apache.catalina.startup.Catalina [ -config {pathname} ] [ -nonaming ] { -h ...

  5. Kinect开发笔记之二Kinect for Windows 2.0新功能

    这是本博客翻译文档的第一篇文章.笔者已经苦逼的竭尽全力的在翻译了.但无奈英语水平也是非常有限.不正确或者不妥当不准确的地方必定会有,还恳请大家留言或者邮件我以批评指正.我会虚心接受. 谢谢大家.   ...

  6. 数组名取地址所算数运算应注意的&quot;trap&quot;

    数组名取地址所算数运算应注意的"trap" 直接看代码: #include <stdio.h> int main() { int array[5]; printf(&q ...

  7. C代码分析器(一个 公开赛冠军)

    最近心血来潮,我希望能写一个通用的代码分析工具(其实这个词有点太.事实上为C代码).看到这几天我看到代码头晕眼花,尽管Source Insight救命,仍然没有足够的智慧思考很多地方. 如今主要遇到的 ...

  8. Linux概念架构的理解(转)

    英文原文:Conceptual Architecture of the Linux Kernel 摘要 Linux kernel成功的两个原因:(1)架构设计支持大量的志愿开发者加入到开发过程中:(2 ...

  9. DDD领域驱动设计初探

    DDD领域驱动设计初探1 前言:又有差不多半个月没写点什么了,感觉这样很对不起自己似的.今天看到一篇博文里面写道:越是忙人越有时间写博客.呵呵,似乎有点道理,博主为了证明自己也是忙人,这不就来学习下D ...

  10. 安装 CentOS 7 后必做的七件事

    原文 安装 CentOS 7 后必做的七件事 CentOS 是最多人用来运行服务器的 Linux 版本,最新版本是 CentOS 7.当你兴趣勃勃地在一台主机或 VPS 上安装 CentOS 7 后, ...