使用Python脚本操作MongoDB的教程


Posted in Python onApril 16, 2015

连接数据库

MongoClient VS Connection

class MongoClient(pymongo.common.BaseObject)
 | Connection to MongoDB.
 |
 | Method resolution order:
 |   MongoClient
 |   pymongo.common.BaseObject
 |   __builtin__.object
 |


class Connection(pymongo.mongo_client.MongoClient)
 | Connection to MongoDB.
 |
 | Method resolution order:
 |   Connection
 |   pymongo.mongo_client.MongoClient
 |   pymongo.common.BaseObject
 |   __builtin__.object

 

从这两个类的继承来看,connection是继承了MongoClient的,建议使用MongoClient而不是使用Connection。(也就是说,MongoClient可以使用方法Connection都可以使用)

from pymongo import MongoClient
client = MongoClient('192.168.40.87', 27037)
db_name = 'TCL_Useraction'
db = client[db_name]
collection_useraction = db['useraction']

 

这里是通过字典的方式访问数据库和集合,同时你也可以通过.(点号)的方式访问
插入数据

save() VS insert()

mongodb的save和insert函数都可以向collection里插入数据,但两者是有两个区别:

一、save函数实际就是根据参数条件,调用了insert或update函数.如果想插入的数据对象存在,insert函数会报错,而save函数是改变原来的对象;如果想插入的对象不存在,那么它们执行相同的插入操作.这里可以用几个字来概括它们两的区别,即所谓"有则改之,无则加之".

二、insert可以一次性插入一个列表,而不用遍历,效率高, save则需要遍历列表,一个个插入。

更新数据

对于单个数据来说,可以更新后使用save方法

update(criteria, objNew, upsert, mult)
criteria: 需要被更新的条件表达式
objNew: 更新表达式
upsert: 如目标记录不存在,是否插入新文档。
multi: 是否更新多个文档。

collection_useraction.update({'gid':last_gid, 'time':l_date}, {'$set':{'gid':last_gid}, '$set':{'time':l_date}, '$addToSet':{'categories':category_data}}, upsert=True)

 
删除数据

db.users.drop() # 删除集合

remove(self, spec_or_id=None, safe=None, multi=True, **kwargs)

# remove() 用于删除单个或全部文档,删除后的文档无法恢复。
id = db.users.find_one({"name":"user2"})["_id"]
db.users.remove(id) # 根据 id 删除一条记录
db.users.remove() # 删除集合里的所有记录
db.users.remove({'yy':5}) # 删除yy=5的记录

查询

  5. 查询

# 查询 age 小于 15 的
  for u in db.users.find({"age":{"$lt":15}}): print u

  5.1 查询一条记录

# 查询 name 等于 user8 的
  for u in db.users.find({"name":"user8"}): print u
# 获取查询的一个
  u2 = db.users.find_one({"name":"user9"}) # 查不到时返回 None
  print u2

  5.2 查询特定键 (fields)

# select name, age from users where age = 21
  for u in db.users.find({"age":21}, ["name", "age"]): print u
  for u in db.users.find(fields = ["name", "age"]): print u

  5.3 排序(SORT)

pymongo.ASCENDING # 也可以用 1 来代替
  pymongo.DESCENDING # 也可以用 -1 来代替
  for u in db.users.find().sort([("age", pymongo.ASCENDING)]): print u  # select * from 集合名 order by 键1
  for u in db.users.find().sort([("age", pymongo.DESCENDING)]): print u # select * from 集合名 order by 键1 desc
  for u in db.users.find().sort([("键1", pymongo.ASCENDING), ("键2", pymongo.DESCENDING)]): print u # select * from 集合名 order by 键1 asc, 键2 desc
  for u in db.users.find(sort = [("键1", pymongo.ASCENDING), ("键2", pymongo.DESCENDING)]): print u # sort 的另一种写法
  for u in db.users.find({"name":"user9"}, sort=[['name',1],['sex',1]], fields = ["name", "age", 'sex']): print u # 组合写法

  5.4 从第几行开始读取(SLICE),读取多少行(LIMIT)
    

# select * from 集合名 skip 2 limit 3
  # MySQL 的写法: select * from 集合名 limit 2, 3
  for u in db.users.find().skip(2).limit(3): print u
  for u in db.users.find(skip = 2, limit = 3): print u

  # 可以用切片代替 skip & limit (mongo 中的 $slice 貌似有点问题)。
  for u in db.users.find()[2:5]: print u

  # 单独的写
  for u in db.users.find().skip(2): print u
  for u in db.users.find(skip=1): print u
  for u in db.users.find().limit(5): print u
  for u in db.users.find(limit = 3): print u

  5.5 多条件查询(Conditional Operators)    # like 的可使用正则表达式查询
   

# select * from users where name = 'user3' and age > 12 and age < 15
  for u in db.users.find({'age': {'$gt': 12, '$lt': 15}, 'name': 'user3'}): print u
  # select * from users where name = 'user1' and age = 21
  for u in db.users.find({"age":21, "name":"user1"}): print u

  5.6 IN
    

for u in db.users.find({"age":{"$in":(23, 26, 32)}}): print u  # select * from users where age in (23, 26, 32)
  for u in db.users.find({"age":{"$nin":(23, 26, 32)}}): print u # select * from users where age not in (23, 26, 32)

  5.7 统计总数(COUNT)
  

print(db.users.count()) # select count(*) from users
  print(db.users.find({"age":{"$gt":30}}).count()) # select count(*) from users where age > 30

  5.8 OR
  

for u in db.users.find({"$or":[{"age":25}, {"age":28}]}): print u # select * from 集合名 where 键1 = 值1 or 键1 = 值2
  for u in db.users.find({"$or":[{"age":{"$lte":23}}, {"age":{"$gte":33}}]}): print u # select * from 集合名 where 键1 <= 值1 or 键1 >= 值2

  6. 是否存在 (exists)

db.users.find({'sex':{'$exists':True}}) # select * from 集合名 where exists 键1
  db.users.find({'sex':{'$exists':False}}) # select * from 集合名 where not exists 键1

  7. 正则表达式查询

for u in db.users.find({"name" : {"$regex" : r"(?i)user[135]"}}, ["name"]): print u # 查询出 name 为 user1, user3, user5

  8. 多级路径的元素值匹配
    Document 采取 JSON-like 这种层级结构,因此我们可以直接用嵌入(Embed)代替传统关系型数据库的关联引用(Reference)。
    MongoDB 支持以 "." 分割的 namespace 路径,条件表达式中的多级路径须用引号

    

# 如果键里面包含数组,只需简单匹配数组属性是否包含该元素即可查询出来
  db.集合名.find_one({'address':"address1"}) # address 是个数组,匹配时仅需包含有即可
  # 查询结果如:{"_id" : ObjectId("4c479885089df9b53474170a"), "name" : "user1", "address" : ["address1", "address2"]}

  # 条件表达式中的多级路径须用引号,以 "." 分割
  u = db.集合名.find_one({"im.qq":12345678})
  # 查询结果如:{"_id" : ObjectId("4c479885089df9b53474170a"), "name" : "user1", "im" : {"msn" : "user1@hotmail.com", "qq" : 12345678}}

  print u['im']['msn'] #显示: user1@hotmail.com

  # 多级路径的更新
  db.集合名.update({"im.qq":12345678}, {'$set':{"im.qq":12345}})

  # 查询包含特定键的
  for u in db.users.find({"im.qq":{'$exists':True}}, {"im.qq":1}): print u
  # 显示如: { "_id" : ObjectId("4c479885089df9b53474170a"), "im" : { "qq" : 12345 } }


  for u in db.users.find({'data':"abc"}): print u
  # 显示如: { "_id" : ObjectId("4c47a481b48cde79c6780df5"), "name" : "user8", "data" : [ { "a" : 1, "b" : 10 }, 3, "abc" ] }
  for u in db.users.find({'data':{'$elemMatch':{'a':1, 'b':{'$gt':5}}}}): print u
  # 显示如: { "_id" : ObjectId("4c47a481b48cde79c6780df5"), "name" : "user8", "data" : [ { "a" : 1, "b" : 10 }, 3, "abc" ] }

    {data:"abc"} 仅简单匹配数组属性是否包含该元素。$elemMatch 则可以处理更复杂的元素查找条件。当然也可以写成如下方式:
    db.集合名.find({"data.a":1, "data.b":{'$gt':5}})

    对数组, 还可以直接使用序号进行操作:
    db.集合名.find({"data.1":3}) # 序号从0开始

   

# 如集合的一列内容
  {"classifyid":"test1",
     "keyword":[
        {"name":'test1', # 将修改此值为 test5 (数组下标从0开始,下标也是用点)
        "frequence":21,
        },
        {"name":'test2', # 子表的查询,会匹配到此值
        "frequence":50,
        },
     ]
  }
  # 子表的修改(子表的其它内容不变)
  db.集合名.update({"classifyid":"test1"}, {"$set":{"keyword.0.name":'test5'}})
  # 子表的查询
  db.集合名.find({"classifyid":"test1", "keyword.0.name":"test2"})

 
操作

  (1) $all: 判断数组属性是否包含全部条件。
   

db.users.insert({'name':"user3", 'data':[1,2,3,4,5,6,7]})
  db.users.insert({'name':"user4", 'data':[1,2,3]})

  for u in db.users.find({'data':{'$all':[2,3,4]}}): print u
  # 显示: { "_id" : ObjectId("4c47a133b48cde79c6780df0"), "name" : "user3", "data" : [ 1, 2, 3, 4, 5, 6, 7 ] }

    注意和 $in 的区别。$in 是检查目标属性值是条件表达式中的一员,而 $all 则要求属性值包含全部条件元素。

  (2) $size: 匹配数组属性元素数量。
    

for u in db.users.find({'data':{'$size':3}}): print u
  # 只显示匹配此数组数量的: { "_id" : ObjectId("4c47a13bb48cde79c6780df1"), "name" : "user4", "data" : [ 1, 2, 3 ] }

  (3) $type: 判断属性类型。
  

for u in db.users.find({'t':{'$type':1}}): print u # 查询数字类型的
  for u in db.users.find({'t':{'$type':2}}): print u # 查询字符串类型的

    类型值:
        double:1
        string: 2
        object: 3
        array: 4
        binary data: 5
        object id: 7
        boolean: 8
        date: 9
        null: 10
        regular expression: 11
        javascript code: 13
        symbol: 14
        javascript code with scope: 15
        32-bit integer: 16
        timestamp: 17
        64-bit integer: 18
        min key: 255
        max key: 127

  (4) $not: 取反,表示返回条件不成立的文档。
    似乎只能跟正则和 $mod 一起使用????
    # 还不知如何使用

  (5) $unset: 和 $set 相反,表示移除文档属性。
 

for u in db.users.find({'name':"user1"}): print u
  # 显示如: { "_id" : ObjectId("4c479885089df9b53474170a"), "name" : "user1", "age" : 15, "address" : [ "address1", "address2" ] }

  db.users.update({'name':"user1"}, {'$unset':{'address':1, 'age':1}})
  for u in db.users.find({'name':"user1"}): print u
  # 显示如: { "_id" : ObjectId("4c479885089df9b53474170a"), "name" : "user1" }

  (6) $push: 和 $ pushAll 都是向数组属性添加元素。# 好像两者没啥区别
  

for u in db.users.find({'name':"user1"}): print u
  # 显示如: { "_id" : ObjectId("4c479885089df9b53474170a"), "age" : 15, "name" : "user1" }

  db.users.update({'name':"user1"}, {'$push':{'data':1}})
  for u in db.users.find({'name':"user1"}): print u
  # 显示如: { "_id" : ObjectId("4c479885089df9b53474170a"), "age" : 15, "data" : [ 1 ], "name" : "user1" }

  db.users.update({'name':"user1"}, {'$pushAll':{'data':[2,3,4,5]}})
  for u in db.users.find({'name':"user1"}): print u
  # 显示如: { "_id" : ObjectId("4c479885089df9b53474170a"), "age" : 15, "data" : [ 1, 2, 3, 4, 5 ], "name" : "user1" }

  (7) $addToSet: 和 $push 类似,不过仅在该元素不存在时才添加 (Set 表示不重复元素集合)。
    

db.users.update({'name':"user2"}, {'$unset':{'data':1}})
  db.users.update({'name':"user2"}, {'$addToSet':{'data':1}})
  db.users.update({'name':"user2"}, {'$addToSet':{'data':1}})
  for u in db.users.find({'name':"user2"}): print u
  # 显示: { "_id" : ObjectId("4c479896089df9b53474170b"), "data" : [ 1 ], "name" : "user2" }

  db.users.update({'name':"user2"}, {'$push':{'data':1}})
  for u in db.users.find({'name':"user2"}): print u
  # 显示: { "_id" : ObjectId("4c479896089df9b53474170b"), "data" : [ 1, 1 ], "name" : "user2" }

  要添加多个元素,使用 $each。
  db.users.update({'name':"user2"}, {'$addToSet':{'data':{'$each':[1,2,3,4]}}})
  for u in db.users.find({'name':"user2"}): print u
  # 显示: {u'age': 12, u'_id': ObjectId('4c479896089df9b53474170b'), u'data': [1, 1, 2, 3, 4], u'name': u'user2'}
  # 貌似不会自动删除重复

  (8) $each 添加多个元素用。
 

db.users.update({'name':"user2"}, {'$unset':{'data':1}})
  db.users.update({'name':"user2"}, {'$addToSet':{'data':1}})
  for u in db.users.find({'name':"user2"}): print u
  # 显示: { "_id" : ObjectId("4c479896089df9b53474170b"), "data" : [ 1 ], "name" : "user2" }

  db.users.update({'name':"user2"}, {'$addToSet':{'data':{'$each':[1,2,3,4]}}})
  for u in db.users.find({'name':"user2"}): print u
  # 显示: {u'age': 12, u'_id': ObjectId('4c479896089df9b53474170b'), u'data': [1, 2, 3, 4], u'name': u'user2'}

  db.users.update({'name':"user2"}, {'$addToSet':{'data':[1,2,3,4]}})
  for u in db.users.find({'name':"user2"}): print u
  # 显示: { "_id" : ObjectId("4c479896089df9b53474170b"), "data" : [ 1, 2, 3, 4, [ 1, 2, 3, 4 ] ], "name" : "user2" }

  db.users.update({'name':"user2"}, {'$unset':{'data':1}})
  db.users.update({'name':"user2"}, {'$addToSet':{'data':[1,2,3,4]}})
  for u in db.users.find({'name':"user2"}): print u
  # 显示: { "_id" : ObjectId("4c47a133b48cde79c6780df0"), "data" : [ [1, 2, 3, 4] ], "name" : "user2" }

  (9) $pop: 移除数组属性的元素(按数组下标移除),$pull 按值移除,$pullAll 移除所有符合提交的元素。
    

db.users.update({'name':"user2"}, {'$unset':{'data':1}})
  db.users.update({'name':"user2"}, {'$addToSet':{'data':{'$each':[1, 2, 3, 4, 5, 6, 7, 2, 3 ]}}})
  for u in db.users.find({'name':"user2"}): print u
  # 显示: { "_id" : ObjectId("4c47a133b48cde79c6780df0"), "data" : [ 1, 2, 3, 4, 5, 6, 7, 2, 3 ], "name" : "user2" }

  db.users.update({'name':"user2"}, {'$pop':{'data':1}}) # 移除最后一个元素
  for u in db.users.find({'name':"user2"}): print u
  # 显示: { "_id" : ObjectId("4c47a133b48cde79c6780df0"), "data" : [ 1, 2, 3, 4, 5, 6, 7, 2 ], "name" : "user2" }

  db.users.update({'name':"user2"}, {'$pop':{'data':-1}}) # 移除第一个元素
  for u in db.users.find({'name':"user2"}): print u
  # 显示: { "_id" : ObjectId("4c47a133b48cde79c6780df0"), "data" : [ 2, 3, 4, 5, 6, 7, 2 ], "name" : "user2" }

  db.users.update({'name':"user2"}, {'$pull':{'data':2}}) # 移除全部 2
  for u in db.users.find({'name':"user2"}): print u
  # 显示: { "_id" : ObjectId("4c47a133b48cde79c6780df0"), "data" : [ 3, 4, 5, 6, 7 ], "name" : "user2" }

  db.users.update({'name':"user2"}, {'$pullAll':{'data':[3,5,6]}}) # 移除 3,5,6
  for u in db.users.find({'name':"user2"}): print u
  # 显示: { "_id" : ObjectId("4c47a133b48cde79c6780df0"), "data" : [ 4, 7 ], "name" : "user2" }

  (10) $where: 用 JS 代码来代替有些丑陋的 $lt、$gt。
    MongoDB 内置了 Javascript Engine (SpiderMonkey)。可直接使用 JS Expression,甚至使用 JS Function 写更复杂的 Code Block。

   

db.users.remove() # 删除集合里的所有记录
  for i in range(10):
    db.users.insert({'name':"user" + str(i), 'age':i})
  for u in db.users.find(): print u
  # 显示如下:
  { "_id" : ObjectId("4c47b3372a9b2be866da226e"), "name" : "user0", "age" : 0 }
  { "_id" : ObjectId("4c47b3372a9b2be866da226f"), "name" : "user1", "age" : 1 }
  { "_id" : ObjectId("4c47b3372a9b2be866da2270"), "name" : "user2", "age" : 2 }
  { "_id" : ObjectId("4c47b3372a9b2be866da2271"), "name" : "user3", "age" : 3 }
  { "_id" : ObjectId("4c47b3372a9b2be866da2272"), "name" : "user4", "age" : 4 }
  { "_id" : ObjectId("4c47b3372a9b2be866da2273"), "name" : "user5", "age" : 5 }
  { "_id" : ObjectId("4c47b3372a9b2be866da2274"), "name" : "user6", "age" : 6 }
  { "_id" : ObjectId("4c47b3372a9b2be866da2275"), "name" : "user7", "age" : 7 }
  { "_id" : ObjectId("4c47b3372a9b2be866da2276"), "name" : "user8", "age" : 8 }
  { "_id" : ObjectId("4c47b3372a9b2be866da2277"), "name" : "user9", "age" : 9 }

  for u in db.users.find({"$where":"this.age > 7 || this.age < 3"}): print u
  # 显示如下:
  {u'age': 0.0, u'_id': ObjectId('4c47b3372a9b2be866da226e'), u'name': u'user0'}
  {u'age': 1.0, u'_id': ObjectId('4c47b3372a9b2be866da226f'), u'name': u'user1'}
  {u'age': 2.0, u'_id': ObjectId('4c47b3372a9b2be866da2270'), u'name': u'user2'}
  {u'age': 8.0, u'_id': ObjectId('4c47b3372a9b2be866da2276'), u'name': u'user8'}
  {u'age': 9.0, u'_id': ObjectId('4c47b3372a9b2be866da2277'), u'name': u'user9'}

  for u in db.users.find().where("this.age > 7 || this.age < 3"): print u
  # 显示如下:
  {u'age': 0.0, u'_id': ObjectId('4c47b3372a9b2be866da226e'), u'name': u'user0'}
  {u'age': 1.0, u'_id': ObjectId('4c47b3372a9b2be866da226f'), u'name': u'user1'}
  {u'age': 2.0, u'_id': ObjectId('4c47b3372a9b2be866da2270'), u'name': u'user2'}
  {u'age': 8.0, u'_id': ObjectId('4c47b3372a9b2be866da2276'), u'name': u'user8'}
  {u'age': 9.0, u'_id': ObjectId('4c47b3372a9b2be866da2277'), u'name': u'user9'}

  # 使用自定义的 function, javascript语法的
  for u in db.users.find().where("function() { return this.age > 7 || this.age < 3;}"): print u
  # 显示如下:
  {u'age': 0.0, u'_id': ObjectId('4c47b3372a9b2be866da226e'), u'name': u'user0'}
  {u'age': 1.0, u'_id': ObjectId('4c47b3372a9b2be866da226f'), u'name': u'user1'}
  {u'age': 2.0, u'_id': ObjectId('4c47b3372a9b2be866da2270'), u'name': u'user2'}
  {u'age': 8.0, u'_id': ObjectId('4c47b3372a9b2be866da2276'), u'name': u'user8'}
  {u'age': 9.0, u'_id': ObjectId('4c47b3372a9b2be866da2277'), u'name': u'user9'}
Python 相关文章推荐
详解django中自定义标签和过滤器
Jul 03 Python
用matplotlib画等高线图详解
Dec 14 Python
tensorflow 1.0用CNN进行图像分类
Apr 15 Python
python中csv文件的若干读写方法小结
Jul 04 Python
pandas DataFrame 行列索引及值的获取的方法
Jul 02 Python
Python二维码生成识别实例详解
Jul 16 Python
Python reversed函数及使用方法解析
Mar 17 Python
python安装及变量名介绍详解
Dec 12 Python
Python创建自己的加密货币的示例
Mar 01 Python
Python中Cookies导出某站用户数据的方法
May 17 Python
Python使用openpyxl批量处理数据
Jun 23 Python
理解python中装饰器的作用
Jul 21 Python
使用Python中的greenlet包实现并发编程的入门教程
Apr 16 #Python
利用Python的Twisted框架实现webshell密码扫描器的教程
Apr 16 #Python
使用Python的Twisted框架实现一个简单的服务器
Apr 16 #Python
使用Python的Twisted框架编写简单的网络客户端
Apr 16 #Python
从Python的源码浅要剖析Python的内存管理
Apr 16 #Python
用Python实现换行符转换的脚本的教程
Apr 16 #Python
Python下的subprocess模块的入门指引
Apr 16 #Python
You might like
PHP和Mysqlweb应用开发核心技术 第1部分 Php基础-1 开始了解php
2011/07/03 PHP
老版本PHP转义Json里的特殊字符的函数
2015/06/08 PHP
PHP中iconv函数知识汇总
2015/07/02 PHP
PHP自定义图片缩放函数实现等比例不失真缩放的方法
2016/08/19 PHP
php简单实现多维数组排序的方法
2016/09/30 PHP
PHP使用strrev翻转中文乱码问题的解决方法
2017/01/13 PHP
PHP基于方差和标准差计算学生成绩的稳定性示例
2017/07/04 PHP
PHP SPL 被遗落的宝石【SPL应用浅析】
2018/04/20 PHP
TP5(thinkPHP5)框架使用ajax实现与后台数据交互的方法小结
2020/02/10 PHP
js href的用法
2010/05/13 Javascript
JQuery对class属性的操作实现按钮开关效果
2013/10/11 Javascript
javascript中一些util方法汇总
2015/06/10 Javascript
js实现3D图片逐张轮播幻灯片特效代码分享
2015/09/09 Javascript
详解vue-cli快速构建项目以及引入bootstrap、jq
2017/05/26 Javascript
Angular 1.x个人使用的经验小结
2017/07/19 Javascript
react-native之ART绘图方法详解
2017/08/08 Javascript
jQuery实现菜单栏导航效果
2017/08/15 jQuery
基于模板引擎Jade的应用(详解)
2017/12/12 Javascript
Vue 实现双向绑定的四种方法
2018/03/16 Javascript
详解element-ui 表单校验 Rules 配置 常用黑科技
2020/07/11 Javascript
vue中的v-model原理,与组件自定义v-model详解
2020/08/04 Javascript
vue style width a href动态拼接问题的解决
2020/08/07 Javascript
numpy排序与集合运算用法示例
2017/12/15 Python
基于python的图片修复程序(实现水印去除)
2018/06/04 Python
python 反向输出字符串的方法
2018/07/16 Python
python opencv实现旋转矩形框裁减功能
2018/07/25 Python
使用11行Python代码盗取了室友的U盘内容
2018/10/23 Python
详解Python:面向对象编程
2019/04/10 Python
Django认证系统实现的web页面实现代码
2019/08/12 Python
python topk()函数求最大和最小值实例
2020/04/02 Python
torchxrayvision包安装过程(附pytorch1.6cpu版安装)
2020/08/26 Python
pip/anaconda修改镜像源,加快python模块安装速度的操作
2021/03/04 Python
家长对孩子评语
2014/01/30 职场文书
婚前协议书怎么写
2014/04/15 职场文书
公务员上班玩游戏检讨书
2014/09/17 职场文书
Matlab求解数组中的最大值及它所在的具体位置
2021/04/16 Python