这是本文档旧的修订版!
MongoDB是一个高性能,开源,无模式的文档型数据库,是当前NoSQL数据库产品中最热门的一种。它在许多场景下可用于替代传统的关系型数据库或键/值存储方式,MongoDB使用C++开发。MongoDB的官方网站地址是:http://www.mongodb.org/。
MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bjson格式,因此可以存储比较复杂的数据类型。MongoDB最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。它是一个面向集合的,模式自由的文档型数据库。
数据数
数据库是一个集合的物理容器。每个数据库获取其自己设定在文件系统上的文件。一个单一的MongoDB服务器通常有多个数据库。
集合
集合是一组MongoDB的文件。它与一个RDBMS表是等效的。一个集合存在于数据库中。集合不强制执行模式。集合中的文档可以有不同的字段。通常情况下,在一个集合中的所有文件都是类似或相关目的。
文档
文档是一组键值对。文档具有动态模式。动态模式是指,在同一个集合的文件不必具有相同一组集合的文档字段或结构,并且相同的字段可以保持不同类型的数据。
在Ubuntu14.04上安装
sudo apt-get install mongodb
安装好后主要的目录和文件如下:
/etc/mongodb.conf #配置文件 /var/lib/mongodb #数据文件存放目录 /var/log/mongodb/mongodb.log #日志文件
查看mongodb版本
gxx@iZ23goxo66aZ:/var/lib/mongodb$ mongod -version db version v2.4.9 Sun Jul 26 09:50:41.115 git version: nogitversion gxx@iZ23goxo66aZ:/var/lib/mongodb$ mongo -version MongoDB shell version: 2.4.9
mongodb默认端口是27017,web控台访问端口28017,注意:要对外开发这两个端口,必须注释掉/etc/mongodb.conf
中的这行#bind_ip = 127.0.0.1
,防止mongodb只监听本地的请求。
如果mongodb启动失败,可以尝试删除/var/lib/mongodb/mongod.lock
gxx@iZ23goxo66aZ:~$ mongo #进入mongodb MongoDB shell version: 2.4.9 #当前版本 connecting to: test #默认进入test数据库 > use test #切换数据库,如果test不存在会创建该数据库 switched to db test > show dbs #查看所有的数据库,新创建的test数据库不会显示在列表中,除非有第一个文档被插入 admin (empty) local 0.078125GB > db #查看当前数据库 test > db.people.insert({"name":"关向辉"}) #插入文档,即使people集合不存在,插入执行前会自动创建集合people > show dbs #查看所有的数据库,看到test数据库 admin (empty) local 0.078125GB test 0.203125GB > db.people.find() #查询people集合里所有的文档,看到文档会自动被mongodb分配一个_id唯一标示,_id是12个字节十六进制数在一个集合的每个文档是唯一的,12个字节被划分如下:_id: ObjectId(4 bytes timestamp, 3 bytes machine id, 2 bytes process id, 3 bytes incrementer) { "_id" : ObjectId("55b45548b327ebd637aa4516"), "name" : "关向辉" } > db.dropDatabase() #删除数据库 { "dropped" : "test", "ok" : 1 } > show dbs #查看所有的数据库 admin (empty) local 0.078125GB > exit #退出mongodb bye gxx@iZ23goxo66aZ:~$
创建集合选项列表
字段 | 类型 | 描述 |
---|---|---|
capped | Boolean | (可选)如果为true,它启用上限集合。上限集合是一个固定大小的集合,当它达到其最大尺寸会自动覆盖最老的条目。 如果指定true,则还需要指定参数的大小。 |
autoIndexID | Boolean | (可选)如果为true,自动创建索引_id字段。默认的值是 false. |
size | number | (可选)指定的上限集合字节的最大尺寸。如果capped 是true,那么还需要指定这个字段。 |
max | number | (可选)指定上限集合允许的最大文件数。 |
gxx@iZ23goxo66aZ:~$ mongo #进入mongodb MongoDB shell version: 2.4.9 #当前版本 connecting to: test #默认进入test数据库 > show dbs #查看所有的数据库 admin (empty) local 0.078125GB > db.createCollection("mycol", { capped : true, autoIndexID : true, size : 6142800, max : 10000 } ) #带参数创建集合 { "ok" : 1 } > show dbs #查看所有的数据库,新增了test admin (empty) local 0.078125GB test 0.078125GB > db.createCollection("mycol2") #不带参数创建集合 { "ok" : 1 } > db.mycol3.insert({"name":"关向辉"}) #插入文档,即使mycol3集合不存在,插入执行前会自动创建集合mycol3 > show collections #查看所有的集合 mycol mycol2 mycol3 system.indexes > db.mycol3.drop() #删除集合 true > show collections #查看所有的集合 mycol mycol2 system.indexes > exit #退出mongodb bye gxx@iZ23goxo66aZ:~$
gxx@iZ23goxo66aZ:~$ mongo #进入mongodb MongoDB shell version: 2.4.9 #当前版本 connecting to: test #默认进入test数据库 > show collections #查看所有的集合 mycol mycol2 system.indexes > db.mycol3.insert({"name":"关向辉"}) #新增一个文档 > db.mycol3.insert([{"syl":"沈云龙"},{"cld":"曹丽东"}]) #新增多个文档,用数组表示 > db.mycol3.insert({"name":"周哲博","age":20,"love":["apple","pear"]}) #新增一个文档 > db.mycol3.find() #查看mycol3集合中所有的文档 { "_id" : ObjectId("55b471effe2d347c6dd80253"), "name" : "关向辉" } { "_id" : ObjectId("55b471f3fe2d347c6dd80254"), "syl" : "沈云龙" } { "_id" : ObjectId("55b471f3fe2d347c6dd80255"), "cld" : "曹丽东" } { "_id" : ObjectId("55b47205fe2d347c6dd80256"), "name" : "周哲博", "age" : 20, "love" : [ "apple", "pear" ] } > db.mycol3.find().pretty() #查看mycol3集合中所有的文档,并且格式化输出 { "_id" : ObjectId("55b471effe2d347c6dd80253"), "name" : "关向辉" } { "_id" : ObjectId("55b471f3fe2d347c6dd80254"), "syl" : "沈云龙" } { "_id" : ObjectId("55b471f3fe2d347c6dd80255"), "cld" : "曹丽东" } { "_id" : ObjectId("55b47205fe2d347c6dd80256"), "name" : "周哲博", "age" : 20, "love" : [ "apple", "pear" ] } > db.mycol3.findOne() #只返回第一个文档 { "_id" : ObjectId("55b471effe2d347c6dd80253"), "name" : "关向辉" } > exit #退出mongodb bye gxx@iZ23goxo66aZ:~$
条件子句
操作 | 语法 | 示例 | RDBMS等效语句 |
---|---|---|---|
Equality | {<key>:<value>} | db.mycol.find({“by”:“yiibai tutorials”}).pretty() | where by = 'yiibai tutorials' |
Less Than | {<key>:{$lt:<value>}} | db.mycol.find({“likes”:{$lt:50}}).pretty() | where likes < 50 |
Less Than Equals | {<key>:{$lte:<value>}} | db.mycol.find({“likes”:{$lte:50}}).pretty() | where likes ⇐ 50 |
Greater Than | {<key>:{$gt:<value>}} | db.mycol.find({“likes”:{$gt:50}}).pretty() | where likes > 50 |
Greater Than Equals | {<key>:{$gte:<value>}} | db.mycol.find({“likes”:{$gte:50}}).pretty() | where likes >= 50 |
Not Equals | {<key>:{$ne:<value>}} | db.mycol.find({“likes”:{$ne:50}}).pretty() | where likes != 50 |
gxx@iZ23goxo66aZ:~$ mongo #进入mongodb MongoDB shell version: 2.4.9 #当前版本 connecting to: test #默认进入test数据库 > db.mycol3.find().pretty() #查看集合mycol3中所有的文档 { "_id" : ObjectId("55b471effe2d347c6dd80253"), "name" : "关向辉" } { "_id" : ObjectId("55b471f3fe2d347c6dd80254"), "syl" : "沈云龙" } { "_id" : ObjectId("55b471f3fe2d347c6dd80255"), "cld" : "曹丽东" } { "_id" : ObjectId("55b47205fe2d347c6dd80256"), "name" : "周哲博", "age" : 20, "love" : [ "apple", "pear" ] } > db.mycol3.find({"name":"周哲博","age":20}) #查看name=周哲博 AND age=20 { "_id" : ObjectId("55b47205fe2d347c6dd80256"), "name" : "周哲博", "age" : 20, "love" : [ "apple", "pear" ] } > db.mycol3.find({$or:[{"name":"周哲博","age":20},{"cld" : "曹丽东"}]}) #查看(name=周哲博 AND age=20)OR(cld=曹丽东) { "_id" : ObjectId("55b471f3fe2d347c6dd80255"), "cld" : "曹丽东" } { "_id" : ObjectId("55b47205fe2d347c6dd80256"), "name" : "周哲博", "age" : 20, "love" : [ "apple", "pear" ] } > db.mycol3.find({"age":{$gt:10},$or:[{"name":"周哲博","age":20},{"cld" : "曹丽东"}]})#查看(age>10)AND((name=周哲博 AND age=20)OR(cld=曹丽东)) { "_id" : ObjectId("55b47205fe2d347c6dd80256"), "name" : "周哲博", "age" : 20, "love" : [ "apple", "pear" ] } > exit #退出mongodb bye gxx@iZ23goxo66aZ:~$
gxx@iZ23goxo66aZ:~$ mongo #进入mongodb MongoDB shell version: 2.4.9 #当前版本 connecting to: test #默认进入test数据库 > db.mycol3.find() #查看集合mycol3所有的文档 { "_id" : ObjectId("55b471effe2d347c6dd80253"), "name" : "关向辉" } { "_id" : ObjectId("55b471f3fe2d347c6dd80254"), "syl" : "沈云龙" } { "_id" : ObjectId("55b471f3fe2d347c6dd80255"), "cld" : "曹丽东" } { "_id" : ObjectId("55b47205fe2d347c6dd80256"), "name" : "周哲博", "age" : 20, "love" : [ "apple", "pear" ] } > db.mycol3.update({"age":{$ne:10}},{$set:{"age":25}}) #update set age=25 where age!=10,只修改第一个文档,想修改多条,必须带上{multi:true} > db.mycol3.find() #查看集合mycol3所有的文档 { "_id" : ObjectId("55b471f3fe2d347c6dd80254"), "syl" : "沈云龙" } { "_id" : ObjectId("55b471f3fe2d347c6dd80255"), "cld" : "曹丽东" } { "_id" : ObjectId("55b47205fe2d347c6dd80256"), "name" : "周哲博", "age" : 20, "love" : [ "apple", "pear" ] } { "_id" : ObjectId("55b471effe2d347c6dd80253"), "age" : 25, "name" : "关向辉" } > db.mycol3.update({"age":{$ne:10}},{$set:{"age":25}},{multi:true}) #带上{multi:true},修改多个文档 > db.mycol3.find() #查看集合mycol3所有的文档 { "_id" : ObjectId("55b47205fe2d347c6dd80256"), "name" : "周哲博", "age" : 25, "love" : [ "apple", "pear" ] } { "_id" : ObjectId("55b471effe2d347c6dd80253"), "age" : 25, "name" : "关向辉" } { "_id" : ObjectId("55b471f3fe2d347c6dd80254"), "age" : 25, "syl" : "沈云龙" } { "_id" : ObjectId("55b471f3fe2d347c6dd80255"), "age" : 25, "cld" : "曹丽东" } > exit #退出mongodb bye gxx@iZ23goxo66aZ:~$
gxx@iZ23goxo66aZ:~$ mongo #进入mongodb MongoDB shell version: 2.4.9 #当前版本 connecting to: test #默认进入test数据库 > db.mycol.insert #查看insert的定义,如果obj._id的文档已存在,插入失败 function ( obj , options, _allow_dot ){ if ( ! obj ) throw "no object passed to insert!"; if ( ! _allow_dot ) { this._validateForStorage( obj ); } if ( typeof( options ) == "undefined" ) options = 0; if ( typeof( obj._id ) == "undefined" && ! Array.isArray( obj ) ){ var tmp = obj; // don't want to modify input obj = {_id: new ObjectId()}; for (var key in tmp){ obj[key] = tmp[key]; } } var startTime = (typeof(_verboseShell) === 'undefined' || !_verboseShell) ? 0 : new Date().getTime(); this._mongo.insert( this._fullName , obj, options ); this._lastID = obj._id; this._printExtraInfo("Inserted", startTime); } > db.mycol.save #查看save的定义,可以看到如果obj._id存在,执行update,不存在执行insert function ( obj ){ if ( obj == null || typeof( obj ) == "undefined" ) throw "can't save a null"; if ( typeof( obj ) == "number" || typeof( obj) == "string" ) throw "can't save a number or string" if ( typeof( obj._id ) == "undefined" ){ obj._id = new ObjectId(); return this.insert( obj ); } else { return this.update( { _id : obj._id } , obj , true ); } } > db.mycol3.find() #查看集合mycol3的所有文档 { "_id" : ObjectId("55b47205fe2d347c6dd80256"), "name" : "周哲博", "age" : 25, "love" : [ "apple", "pear" ] } { "_id" : ObjectId("55b471effe2d347c6dd80253"), "age" : 25, "name" : "关向辉" } { "_id" : ObjectId("55b471f3fe2d347c6dd80254"), "age" : 25, "syl" : "沈云龙" } { "_id" : ObjectId("55b471f3fe2d347c6dd80255"), "age" : 25, "cld" : "曹丽东" } > db.mycol3.insert({ "_id" : ObjectId("55b471f3fe2d347c6dd80255"), "age" : 30, "cld" : "曹丽东" }) #_id=55b471f3fe2d347c6dd80255的文档已存在,插入失败 E11000 duplicate key error index: test.mycol3.$_id_ dup key: { : ObjectId('55b471f3fe2d347c6dd80255') } > db.mycol3.save({ "_id" : ObjectId("55b471f3fe2d347c6dd80255"), "age" : 30, "cld" : "曹丽东" }) #_id=55b471f3fe2d347c6dd80255的文档如果不存在,执行insert插入,如果已存在,执行update修改 > db.mycol3.find() #查看集合mycol3的所有文档,_id=55b471f3fe2d347c6dd80255的age已被修改 { "_id" : ObjectId("55b47205fe2d347c6dd80256"), "name" : "周哲博", "age" : 25, "love" : [ "apple", "pear" ] } { "_id" : ObjectId("55b471effe2d347c6dd80253"), "age" : 25, "name" : "关向辉" } { "_id" : ObjectId("55b471f3fe2d347c6dd80254"), "age" : 25, "syl" : "沈云龙" } { "_id" : ObjectId("55b471f3fe2d347c6dd80255"), "age" : 30, "cld" : "曹丽东" } > exit #退出mongodb bye gxx@iZ23goxo66aZ:~$
gxx@iZ23goxo66aZ:~$ mongo #进入mongodb MongoDB shell version: 2.4.9 #当前版本 connecting to: test #默认进入test数据库 > db.mycol3.find() #查看集合mycol3的所有文档 { "_id" : ObjectId("55b47205fe2d347c6dd80256"), "name" : "周哲博", "age" : 25, "love" : [ "apple", "pear" ] } { "_id" : ObjectId("55b471effe2d347c6dd80253"), "age" : 25, "name" : "关向辉" } { "_id" : ObjectId("55b471f3fe2d347c6dd80254"), "age" : 25, "syl" : "沈云龙" } { "_id" : ObjectId("55b471f3fe2d347c6dd80255"), "age" : 30, "cld" : "曹丽东" } > db.mycol3.remove({'age':30}) #删除集合mycol3中age=30的文档 > db.mycol3.find() #查看集合mycol3的所有文档 { "_id" : ObjectId("55b47205fe2d347c6dd80256"), "name" : "周哲博", "age" : 25, "love" : [ "apple", "pear" ] } { "_id" : ObjectId("55b471effe2d347c6dd80253"), "age" : 25, "name" : "关向辉" } { "_id" : ObjectId("55b471f3fe2d347c6dd80254"), "age" : 25, "syl" : "沈云龙" } > db.mycol3.remove() #删除集合mycol3所有文档 > db.mycol3.find() #查看集合mycol3的所有文档,已被清空 > exit #退出mongodb bye gxx@iZ23goxo66aZ:~$
gxx@iZ23goxo66aZ:~$ mongo #进入mongodb MongoDB shell version: 2.4.9 #当前版本 connecting to: test #默认进入test数据库 > db.mycol3.insert({"name":"关向辉"}) #插入文档 > db.mycol3.insert([{"syl":"沈云龙"},{"cld":"曹丽东"}]) #插入多个文档,使用数组 > db.mycol3.insert({"name":"周哲博","age":20,"love":["apple","pear"]}) #插入文档 > db.mycol3.find() #查看集合mycol3的所有文档 { "_id" : ObjectId("55b47f3b0a35077a1f579fe0"), "name" : "关向辉" } { "_id" : ObjectId("55b47f420a35077a1f579fe1"), "syl" : "沈云龙" } { "_id" : ObjectId("55b47f420a35077a1f579fe2"), "cld" : "曹丽东" } { "_id" : ObjectId("55b47f460a35077a1f579fe3"), "name" : "周哲博", "age" : 20, "love" : [ "apple", "pear" ] } > db.mycol3.find({},{"_id":0,"name":1,"cld":1}) #查看集合mycol3的所有文档,并投影字段,显示name和cld字段,设置字段_id为0或者不设置字段syl,age,love等都为不投影 { "name" : "关向辉" } { } { "cld" : "曹丽东" } { "name" : "周哲博" } > exit #退出mongodb bye gxx@iZ23goxo66aZ:~$
gxx@iZ23goxo66aZ:~$ mongo #进入mongodb MongoDB shell version: 2.4.9 #当前版本 connecting to: test #默认进入test数据库 > db.mycol3.find({"age":{$ne:20}}) #查看集合mycol3的age!=20的文档 { "_id" : ObjectId("55b47f3b0a35077a1f579fe0"), "name" : "关向辉" } { "_id" : ObjectId("55b47f420a35077a1f579fe1"), "syl" : "沈云龙" } { "_id" : ObjectId("55b47f420a35077a1f579fe2"), "cld" : "曹丽东" } > db.mycol3.find({"age":{$ne:20}}).limit(2) #查看集合mycol3的age!=20的文档,只返回2条 { "_id" : ObjectId("55b47f3b0a35077a1f579fe0"), "name" : "关向辉" } { "_id" : ObjectId("55b47f420a35077a1f579fe1"), "syl" : "沈云龙" } > exit #退出mongodb bye gxx@iZ23goxo66aZ:~$