MongoDB学习笔记(2)
Week2介绍的是MongoDB的CRUD,主要是mongo shell和pymongo的使用。
在MongoDB中,和CRUD基本对应的是:
- C -> Insert
- R -> Find
- U -> Update
- D -> Remove
总体来说,MongoDB的操作对程序员来说是非常友好的,以programming language APIs(object/function call)的方式操作DB。
实际和MongoDB server通信使用的是Mongo Wire Protocol:
The Mongo Wire Protocol is a simple socket-based,
request-response style protocol.
Clients communicate with the database server through a
regular TCP/IP socket
简单来说就是将描述操作的JSON Object序列化成BSON,通过socket扔给mongod解析并处理。
MongoDB内部实际使用的都是BSON,binary格式的JSON超集,而mongo shell实际上是个交互式的javascript解释器,你可以运行基本的js语句。
每个MongoDB存储的Document都有一个唯一标示的字段:_id ,如果你没有明确指定,MongoDB会自动给你生成一个,形如"_id" : ObjectId("50906d7fa3c412bb040eb577")
###Insert/Update的一些例子:
* db.collection.insert({"name":"value"})
* //添加一个document,参数直接是json object
* db.collection.findOne()
* //随机返回一个document
* db.users.findOne({"username":"dwight"},{"email":true,"_id":false})
* //查找username为dwight的所有documents,只显示email字段
* db.collection.find()
* //只会返回20项,默认情况下server 10min后会关闭这个cursor###Query operator一些例子:
* //mongodb中的Query operator基本上是以embeded document的方式来处理的:
* db.grades.findOne({"student_id":{$gt:20}})
* //还有$gt $lte
* $exists
* //看字段是否存在
* $type
* //根据字段的类型来查找
* db.users.find({name:{$regex:"q"},email:{$exists:true}})
* //$regex 支持正则表达式,libpcre/perl
* $or:[{score:{"$lt:50"},{}]
* //逻辑or,特别之处是一个prefix operator,原因主要是为了符合json的格式
* db.scores.find( { score : { $gt : 50 }, score : { $lt : 60 } } );
* - //$and, 如果两个相同的key,起作用的是会是后一个key的值,这是个小陷阱###多态查询:
> db.movies.find()
{ "_id" : ObjectId("5098fa4d1d45e3ddd35f98a1"), "name" : "gone with the wind" }
{ "_id" : ObjectId("5098fa8a1d45e3ddd35f98a2"), "name" : [ "inception", "killer" ] }
{ "_id" : ObjectId("5098faa41d45e3ddd35f98a3"), "name" : "inception" }
> db.movies.find({'name':'inception'})
{ "_id" : ObjectId("5098fa8a1d45e3ddd35f98a2"), "name" : [ "inception", "killer" ] }
{ "_id" : ObjectId("5098faa41d45e3ddd35f98a3"), "name" : "inception" }###Dot notation 如果要查询embeded document,MongoDB也提供了dot notation的方式,值得注意的是dot notaion必须用引号括起来才行。
###sort/skip/limit:
* db.scores.find({"type":"exam"}).sort({score:-1}).skip(50).limit(20)
* //find()返回的是一个cursor, 可以进行排序,或者跳过,返回限定数目的结果,
* //这里值得注意的地方是,sort/skip/limit实际上都是在server上处理的
* 而且顺序一定是sort->skip->limit,真正执行query实际返回结果的时候###Update/Remove/Drop
* db.scores.update({…})
* //update默认的行为除了_id,替换成新的json document
* //如果需要删除某个key,可以使用$unset:{key:1},修改可以使用$set/$inc:
* db.scores.update({score:{$lt:70}},{$inc:{score:20}},{multi:true})
* //给所有分数低于70的加上20, multi很重要
* //默认update只会更新一个返回的结果,这个多半是随机的
* //multi的意思是更新所有,实现上是cooperative的write/yeild.
* db.scores.remove()/drop()
//drop比remove快很多,remove相当于批量update,drop则时直接删除数据结构###Misc
* db.runCommand({"getLastError":1})
* //error field 如果是空则表明命令执行成功了,否则会有出错信息
* db.scores.count()
* //计数###pymongo pymongo风格和python基本保持一致,这也可以算做对程序员友好~,比如:
- findOne()在python中就是find_one()
- 还有一些参数上的略微不同:比如cursor的sort(),参数是tuple的数组,原因是dict是无序的,这里也是个小陷阱。
- update()的第三个参数不是json object而是直接
multi=True upsert=True - 一些helper func:save()/find_and_modify()
blog comments powered by Disqus