MongoDB的upsert狀態判斷和pymongo使用方法


在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

記錄完成


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM