python操作mongo

在python中,连接并操作mongo主要使用了pymongo库。

3.6版本的mongo安装后需要创建/data/db文件夹,并设置其权限或改变拥有者。通过nohup mongod &方式可以将mongo以后台服务方式启动。


mongo连接

说明:本文中的mongo为单节点环境,集群环境见:mongo集群

先安装mongo(见官方文档,推荐使用下载tar包的方式安装),并创建一个库:mytest,collection为person,插入一条记录:_id:1。连接并查询:

import pymongo

client = pymongo.MongoClient(host='localhost', port=27017)
db = client.mytest
collection = db.person
result = collection.find_one()
print result

输出结果如下:

{u'_id':1.0}

首先,要连接上mongoDB,通过pymongo库里的MongoClient来实现。传入host和port两个参数,或者直接传入一个连接字符串也行,如下所示:

client = MongoClient('mongodb://localhost:27017/')

然后,获取到db和collection。client.mytest和client[‘mytest’]这两种方式是一样的效果。同样地,指定操作集合时,db.person和db[‘person’]也是一样的。

当collection中存在数据时,可通过collection的find()或find_one()方法来查询结果,其中find_one()查询得到的是单个结果,而find()则返回一个生成器对象。

CRUD操作

insert

现在往collection中插入数据。

import pymongo

client = pymongo.MongoClient(host='localhost', port=27017)
db = client.mytest
collection = db.person
person = { "name": "Mike"}
collection.insert(person)
cur = collection.find()
for c in cur:    
	print c

输出结果如下:

{u'_id':1.0}
{u'_id': ObjectId('5cd8e716fcc8c12d8ee405ce'), u'name': u'Mike'}

第一条数据是从外面插入的,指定了_id为1。此处插入name为Mike的这条数据,由系统自动生成了ObjectId(当你创建文档时,可以通过给_id键赋值来覆写自动创建的ObjectID值)。

在Mongo3.x版本中官方已经不推荐使用insert()方法,而是替换成了insert_one()和insert_many(),用于插入单条记录和多条记录。
insert方法返回的结果是标识id(_id)列表,而insert_one方法返回的是一个InsertOneResult对象,通过inserted_id属性获取_id。

find

find()方法返回一个生成器对象,需要进行遍历才能得到对应的dict对象。而find_one()方法直接返回的就是一个dict对象。

import pymongo

client = pymongo.Mongo
Client(host='localhost', port=27017)
db = client.mytest
collection = db.person
curson = collection.find({"name": "Mike"})
print("curson type is %s" % type(curson))
for c in curson:    
	print("c type is %s " % type(c))    
	print c

结果如下:

    curson type is <class 'pymongo.cursor.Cursor'>
    c type is <type 'dict'> 
    {u'_id': ObjectId('5cd8e716fcc8c12d8ee405ce'), u'name': u'Mike'}

除了字符串精确匹配查询之外,对于整形,支持以下操作:

符号含义示例
$lt,$gt小于, 大于{‘age’:{’$lt’: 20}}
$lte, $gte小于等于,大于等于{‘age’:{’$lte’: 20}}
$ne不等于{‘age’: {’$ne’:20}}
$in在范围内{‘age’: {’$in’: [20,23]}}
$nin不在范围内{‘age’: {’$nin’:[20,23]}}
$or或者‘$or’: [{‘age’: 10}, {‘age’: 60}]

还有其他一些高级的用法如下所示:

符号含义示例说明
$regex正则匹配{‘name’: {’$regex’: ‘^M.*’}}
$exists属性是否存在{‘name’: {’$exists’: True}}
$type类型判断{‘age’: {’$type’: ‘int’}}age的类型为int
$mod数字模操作{‘age’: {’$mod’: [5, 0]}}年龄模5余0
$text文本查询{’$text’:{’$search’: ‘Mike’}}text类型的属性中包含Mike字符串
$where高级条件查询{’$where’: ‘obj.fans_count == obj.follows_count’}自身粉丝数等于关注数

分组聚合
db.xx.aggregate([{$group:{_id:’$name’, count:{$sum:1}}}])

count,sort,skip,limit

计数直接调用count函数:
count = collection.find().count()count = collection.find({'name':'Mike'}).count()
排序直接调用sort函数:
results = collection.find().sort('name', pymongo.ASCENDING),降序为pymongo.DESCENDING
偏移直接调用skip函数:

results = collection.find().sort('name', pymongo.ASCENDING).skip(2)

限制查询结果数直接调用limit函数:

results = collection.find().sort('name', pymongo.ASCENDING).skip(2).limit(2)

update

使用update()进行数据更新:

condition = {'name': 'Mike'}
student = collection.find_one(condition)
student['age'] = 25
result = collection.update(condition, student)
print result

运行结果如下:

{'ok': 1, 'nModified': 1, 'n': 1, 'updatedExisting': True}

返回字典形式结果, ok表示执行成功,nModified表示影响条数。

也可以使用$set操作符对数据进行更新,如下所示:

result = collection.update(condition, {'$set': student})

是否使用$set的区别在于:
不使用$set时,会使用当前更新的字典对象替换原对象,新对象中不含而旧对象中存在的字段会消失。
使用$set时,则只更新新对象中存在的字段,旧对象的其他字段保持不变。

实际上,update也是官方不推荐使用的方法,推荐的是update_oneupdate_many,它们的第二个参数必须使用$set作为字典的键名,不允许直接传入修改后的新字典对象。

result = collection.update_one({"name": "Mike"}, {"$set": {"name": "Tom"}})
print result, result.matched_count, result.modified_count
cur = collection.find()
for r in cur:    
	print r

update_one和update_many方法返回的结果是一个UpdateResult,其中matched_count属性和modified_count属性分别表示匹配的数据条数和影响的数据条数。

update_many会更新所有符合条件的数据, 其参数为:(query,update,upsert=False,multi=False), 第三个参数和第四个参数的默认值均为false,含义:不存在就插入;更新多条。

批量更新

update_many可以更新符合条件的多条数据,这是一种意义上的批量更新。还有另外一种批量更新,指的是将多次更新操作一起执行,如下所示:

op1 = pymongo.UpdateOne({"name": "Mike"}, {"$set": {"name": "Tom"}})
op2 = pymongo.UpdateOne({"name": "Jack"}, {"$set": {"name":"Hanse"}})
update_operations.append(op1)
update_operations.append(op2)
collection.bulk_write(ops)

批量更新时有个坑要注意下,bulk_write函数实际上有三个参数,后两个参数意义分别是:执行操作的有序性和是否验证文档规则约束。根据需要进行指定,而不指定的情况下分别为True和False。当在认证登录的情况下,如果将后一个参数指定为True,则此更新操作会报权限错误。

delete

删除操作通过remove函数来进行,在参数中指定删除条件:

result = collection.remove({"name": "Mike"})

remove返回结果是一个dict对象:

{'ok': 1, 'n': 1}

表示执行成功,删除条数为1。

同样地,官方推荐方法为delete_one()和delete_many(),返回结果是DeleteResult对象,其中的deleted_count属性为删除的数据条数。

组合操作

其他还有一些组合操作,如find_one_and_delete(),finde_one_and_replace,find_one_and_update。

用户权限

通过

use admin; 
db.createUser({user:"root", pwd:"root", roles:[{"role":"dbAdminAnyDatabase", "db":"admin"},{"role":"userAdminAnyDatabase","db":"admin"}]})

来添加用户。

userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限
dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。
dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile
userAdmin:允许用户向system.users集合写入,可以指定数据库里创建、删除和管理用户
root:只在admin数据库中可用。超级账号,超级权限

开启服务时通过–auth来开启验证:
nohup mongod --auth &
通过
mongo -uroot -proot -authenticationDatabase admin进行登录。登录后切换到admin库(默认是test库),通过命令show users可以查看admin库添加的用户。

但切换到mytest库后仍然不具有访问权限。添加mytest库用户:

use mytest
db.createUser({user:"root", pwd:"root", roles:[{"role":"readWrite","db":"mytest"}]})

readWrite:允许用户读写指定数据库

重新认证登录:

mongo -uroot -proot -authenticationDatabase mytest

切换到mytest之后访问person集合:

use mytest
db.person.find()

当前登录用户对mytest库具有读写权限,因此可以访问集合。

参考

[1]https://www.jianshu.com/p/430ef6441601
[2]https://juejin.im/post/5addbd0e518825671f2f62ee
[3]https://docs.mongodb.com/manual/reference/operator/query/
[4]https://blog.csdn.net/uevol14/article/details/53885779

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值