使用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的URLconf中使用多个视图前缀的方法
Jul 18 Python
python字典的常用操作方法小结
May 16 Python
对Python中gensim库word2vec的使用详解
May 08 Python
python使用zip将list转为json的方法
Dec 31 Python
python获取微信企业号打卡数据并生成windows计划任务
Apr 30 Python
python爬虫之遍历单个域名
Nov 20 Python
Python 类的魔法属性用法实例分析
Nov 21 Python
对Keras中predict()方法和predict_classes()方法的区别说明
Jun 09 Python
Python 多进程、多线程效率对比
Nov 19 Python
Pycharm plot独立窗口显示的操作
Dec 11 Python
python中doctest库实例用法
Dec 31 Python
Python读取ini配置文件传参的简单示例
Jan 05 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
Breeze 文章管理系统 v1.0.0正式发布
2006/12/14 PHP
php中大括号作用介绍
2012/03/22 PHP
php获取ip的三个属性区别介绍(HTTP_X_FORWARDED_FOR,HTTP_VIA,REMOTE_ADDR)
2012/09/23 PHP
微信公众平台开发之天气预报功能
2015/08/31 PHP
Laravel 5.4.36中session没有保存成功问题的解决
2018/02/19 PHP
PHP实现常用排序算法的方法
2020/02/05 PHP
JavaScript 创建对象和构造类实现代码
2009/07/30 Javascript
JavaScript中的匀速运动和变速(缓冲)运动详细介绍
2012/11/11 Javascript
利用window.name实现windowStorage代码分享
2014/01/02 Javascript
jQuery xml字符串的解析、读取及查找方法
2016/03/01 Javascript
jQuery validate插件功能与用法详解
2016/12/15 Javascript
js实现带简单弹性运动的导航条
2017/02/22 Javascript
详谈JS中数组的迭代方法和归并方法
2017/08/11 Javascript
vue不通过路由直接获取url中参数的方法示例
2017/08/24 Javascript
React Native 使用Fetch发送网络请求的示例代码
2017/12/02 Javascript
Vue实现根据hash高亮选项卡
2019/05/27 Javascript
基于VUE实现判断设备是PC还是移动端
2020/07/03 Javascript
Vue element-ui父组件控制子组件的表单校验操作
2020/07/17 Javascript
python中使用pyhook实现键盘监控的例子
2014/07/18 Python
LRUCache的实现原理及利用python实现的方法
2017/11/21 Python
Python深度优先算法生成迷宫
2018/01/22 Python
Django rest framework实现分页的示例
2018/05/24 Python
Python实现的爬取网易动态评论操作示例
2018/06/06 Python
Django实战之用户认证(初始配置)
2018/07/16 Python
python使用itchat模块给心爱的人每天发天气预报
2019/11/25 Python
python3中numpy函数tile的用法详解
2019/12/04 Python
快速了解Python开发环境Spyder
2020/06/29 Python
HTML5 3D衣服摇摆动画特效
2016/03/17 HTML / CSS
如何在Shell脚本中使用函数
2015/09/06 面试题
消防安全管理制度
2014/02/01 职场文书
幼师小班个人总结
2015/02/12 职场文书
2015年党员个人工作总结
2015/05/13 职场文书
运动会观后感
2015/06/09 职场文书
庆元旦主持词
2015/07/06 职场文书
学校运动会加油词
2015/07/18 职场文书
队名及霸气口号大全
2015/12/25 职场文书