欢迎投稿

今日深度:

操作MongoDB,

操作MongoDB,


有用的命令

db.help
db.collectionname.help

  

时区问题

> db.test.insert({"date":new Date("2012-2-2"),"num":1})
> db.test.insert({"date":new Date("2012-02-02"),"num":2})
> db.test.insert({"date":new Date("2012-02-02 00:00:00"),"num":3})
> db.test.find()
{ "_id" : ObjectId("538ebd629ceb8ee60dcd6a0e"), "date" : ISODate("2012-02-01T16:00:00Z"), "num" : 1 }
{ "_id" : ObjectId("538ebd6e9ceb8ee60dcd6a0f"), "date" : ISODate("2012-02-02T00:00:00Z"), "num" : 2 }
{ "_id" : ObjectId("538ebd7e9ceb8ee60dcd6a10"), "date" : ISODate("2012-02-01T16:00:00Z"), "num" : 3 }
> db.test.find()
{ "_id" : ObjectId("538ebd629ceb8ee60dcd6a0e"), "date" : ISODate("2012-02-01T16:00:00Z"), "num" : 1 }
{ "_id" : ObjectId("538ebd6e9ceb8ee60dcd6a0f"), "date" : ISODate("2012-02-02T00:00:00Z"), "num" : 2 }
{ "_id" : ObjectId("538ebd7e9ceb8ee60dcd6a10"), "date" : ISODate("2012-02-01T16:00:00Z"), "num" : 3 }
> 

 

开启子节点的读

rs.slaveOk();

 

开启 Profiling  功能 

有两种方式可以控制 Profiling  的开关和级别,第一种是直接在启动参数里直接进行设置。 启动MongoDB时加上–profile=级别  即可。  也可以在客户端调用 db.setProfilingLevel(级别)  命令来实时配置,Profiler  信息保存在 system.profile 中。我们可以通过db.getProfilingLevel()命令来获取当前的Profile级别,类似如下操作 

 db.setProfilingLevel(2);    

上面profile的级别可以取0,1,2  三个值,他们表示的意义如下: 

0 –  不开启 

1 –  记录慢命令 (默认为>100ms)  

2 –  记录所有命令  

 

Profile  记录在级别 1 时会记录慢命令,那么这个慢的定义是什么?上面我们说到其默认为100ms,当然有默认就有设置,其设置方法和级别一样有两种,一种是通过添加–slowms 启动参数配置。第二种是调用db.setProfilingLevel时加上第二个参数: 

db.setProfilingLevel( 1 , 10 ); 

 

查询 Profiling  记录 

 

与 MySQL 的慢查询日志不同,MongoDB Profile  记录是直接存在系统 db 里的,记录位置 system.profile  ,所以,我们只要查询这个 Collection 的记录就可以获取到我们的 Profile  记录了。列出执行时间长于某一限度(5ms)的 Profile  记录: 

db.system.profile.find( { millis : { $gt : 5 } } ) 

 

查看最新的 Profile  记录: 

 db.system.profile.find().sort({$natural:-1}).limit(1) 

 { "ts" : ISODate("2012-05-20T16:50:36.321Z"), "info" : "query test.system.profile reslen:1219 

nscanned:8  \nquery: { query: {}, orderby: { $natural: -1.0 } }  nreturned:8 bytes:1203", "millis" :  0 } 

 

字段说明 

ts:  该命令在何时执行  info:  本命令的详细信息  reslen:  返回结果集的大小  nscanned:  本次查询扫描的记录数  nreturned:  本次查询实际返回的结果集  millis:  该命令执行耗时,以毫秒记  

 

MongoDB Shell  还提供了一个比较简洁的命令 show profile,可列出最近5 条执行时间超过

1ms的 Profile  记录。  

 

db.ttl.ensureIndex({"Date": 1}, {expireAfterSeconds: 300})

cfg = { _id: "set1", members: [

... { _id:0, host:"10.96.16.118:27017" },
... { _id:1, host:"10.96.16.119:27017" },
... { _id:2, host:"10.96.22.40:27022" , "arbiterOnly": true}
... ]}

rs.initiate(cfg)

收缩日志

在admin数据库下执行

db.runCommand({logRotate:1}) mongodb会重新写个日志

 

 

上篇讲过每个集群结点都有一个priority属性,默认为1。要改变一个实例的角色,我们只需要给新的实例设置一个高于当前Primary的priority就可以实现了。

注意因为只有Primary结点是可写的,所以重新配置群集的操作只能在Primary结点上进行。

复制代码
rs0:PRIMARY> conf.members[1].priority = 2
2
rs0:PRIMARY> rs.reconfig(conf)
Fri Jan 24 15:25:36.069 DBClientCursor::init call() failed
Fri Jan 24 15:25:36.070 trying reconnect to localhost:27011
Fri Jan 24 15:25:36.070 reconnect localhost:27011 ok
reconnected to server after rs command (which is normal)

rs0:SECONDARY>
复制代码

 

 

追加内容(numa服务器下mongodb的部署)

numactl --interleave=all ./mongod -f ./mongodb.conf

0:追加内容(MapReduce

MapReduce是一种计算模型,简单的说就是将大批量的工作(数据)分解(MAP)执行,然后再将结果合并成最终结果(REDUCE)。这样做的好处是可以在任务被分解后,可以通过大量机器进行并行计算,减少整个操作的时间。

举例1

数据

View Code
for (var i = 0; i < 10; i++) {
... var u = { name : "user" + i, age : i, sex : i % 2 };
... db.users.insert(u);
... }

A:男女同学分别的人数(select Sex,count(*) from users group by Sex)

m = function() { emit(this.sex, 1) }
r = function(key, values) {
... ... var x = 0;
... ... values.forEach(function(v) { x += v ;});
... ... return x;
... ... }

B: 男女同学的平均年龄(select Sex,avg(age) from users group by Sex)

m = function() { emit(this.sex, this.age) }
r = function(key, values) {
... ... var x = 0,num=0;
... ... values.forEach(function(v) { x += v ;num++});
... ... return x/num;
... ... }

另一个例子,计算一个标签系统中每个标签出现的次数

> db.things.insert( { _id : 1, tags : ['dog', 'cat'] } );  
> db.things.insert( { _id : 2, tags : ['cat'] } );  
> db.things.insert( { _id : 3, tags : ['mouse', 'cat', 'dog'] } );  
> db.things.insert( { _id : 4, tags : []  } );  
  
> // map function  
> m = function(){  
...    this.tags.forEach(  
...        function(z){  
...            emit( z , { count : 1 } );  
...        }  
...    );  
...};  
  
> // reduce function  
> r = function( key , values ){  
...    var total = 0;  
...    for ( var i=0; i<values.length; i++ )  
...        total += values[i].count;  
...    return { count : total };  
...};  
  
> res = db.things.mapReduce(m, r, { out : "myoutput" } );  
> res  
{  
    "result" : "myoutput",  
    "timeMillis" : 12,  
    "counts" : {  
        "input" : 4,  
        "emit" : 6,  
        "output" : 3  
    },  
    "ok" : 1,  
}  
> db.myoutput.find()  
{"_id" : "cat" , "value" : {"count" : 3}}  
{"_id" : "dog" , "value" : {"count" : 2}}  
{"_id" : "mouse" , "value" : {"count" : 1}}  
  
> db.myoutput.drop()  

从上面的三个列子我们可以看出

1:map函数只要用于从样本空间中过滤出key-values集合,其中key就是emit的第一个参数,values就是第二个参数

2:reduce函数主要是要将key-values转换成key-value的形式,也就是把这一个集合变成一个单一的值

 

 

 

1:各文件作用

mongo.exe 客户端程序
mongod.exe 服务端程序
mongodump.exe 备份程序
mongoexport.exe 数据导出程序
mongofiles.exe GridFS工具,内建的分布式文件系统
mongoimport.exe 数据导入程序
mongorestore.exe 数据恢复程序
mongos.exe 数据分片程序,支持数据的横向扩展
mongostat.exe 监视程序

2:部署

MongoDB可以以DOS作为容器运行也可以以服务形式运行。

以DOS为容器运行

mongod --dbpath E:\mongodb\bin\db -- port 27020 --logpath E:\mongodb\bin\log.txt
--directoryperdb 让系统为每个 DB 创建一个独立子目录
与 Logging 有关的参数除了 --logpath,还有 --logappend 和 --verbose。

默认情况下,Logging 是覆盖模式(overwrite),通过 --logappend 可以添加模式记录日志。
参数 --verbose 设置记录等级,相当于 -v,更多的级别包括 -vv 直到 -vvvvv。与之相对的是 --quiet,生成最少的日志信息。
还可以用 --cpu 记录 CPU 的相关信息。
admin.serverStatus() 命令可以获取 MongoDB 的运行统计信息。(uptime: 服务器运行时间(秒)。localTime: 服务器本地时间。mem: 服务器内存信息。connections: 当前连接数。opcounters: 操作统计。)
db.stats 查看数据库状态信息。

以WindowsServer为容器运行

mongod --dbpath E:\mongodb\bin\db --logpath E:\mongodb\bin\log.txt --install

以服务方式运行不能指定端口。

验证方法

mongo --port 27017
show dbs

3:复制数据库

同数据库系统复制

E:\mongodb\bin>mongo
MongoDB shell version: 1.8.2
connecting to: test
> use person
switched to db person
> for (var i = 0; i < 10; i++) db.person.save({id : + i})
> show dbs
admin (empty)
local (empty)
person 0.03125GB
> db.copyDatabase("person","person1")
{ "ok" : 1 }
> show dbs
admin (empty)
local (empty)
person 0.03125GB
person1 0.03125GB

异数据库系统复制

E:\mongodb\bin>mongo --port 27020
MongoDB shell version: 1.8.2
connecting to: 127.0.0.1:27020/test
> show dbs
admin (empty)
local (empty)
> db.copyDatabase("person", "person2", "10.53.139.138:27017")
{ "ok" : 1 }
> show dbs
admin (empty)
local (empty)
person2 0.03125GB

4:锁定数据库

> db.person.find()
{ "_id" : ObjectId("4e27baae7ff2440ba274d767"), "id" : 0 }
{ "_id" : ObjectId("4e27baae7ff2440ba274d768"), "id" : 1 }
{ "_id" : ObjectId("4e27baae7ff2440ba274d769"), "id" : 2 }
{ "_id" : ObjectId("4e27baae7ff2440ba274d76a"), "id" : 3 }
{ "_id" : ObjectId("4e27baae7ff2440ba274d76b"), "id" : 4 }
{ "_id" : ObjectId("4e27baae7ff2440ba274d76c"), "id" : 5 }
{ "_id" : ObjectId("4e27baae7ff2440ba274d76d"), "id" : 6 }
{ "_id" : ObjectId("4e27baae7ff2440ba274d76e"), "id" : 7 }
{ "_id" : ObjectId("4e27baae7ff2440ba274d76f"), "id" : 8 }
{ "_id" : ObjectId("4e27baae7ff2440ba274d770"), "id" : 9 }
{ "_id" : ObjectId("4e27bf5c9033de6afd328581"), "id" : 10 }
> admin=db.getSisterDB("admin")
admin
> admin.runCommand({fsync : 1, lock : 1}) //锁定
{
"info" : "now locked against writes, use db.$cmd.sys.unlock.findOne() to
unlock",
"ok" : 1
}
> db.person.find()//锁定期间可读
{ "_id" : ObjectId("4e27baae7ff2440ba274d767"), "id" : 0 }
{ "_id" : ObjectId("4e27baae7ff2440ba274d768"), "id" : 1 }
{ "_id" : ObjectId("4e27baae7ff2440ba274d769"), "id" : 2 }
{ "_id" : ObjectId("4e27baae7ff2440ba274d76a"), "id" : 3 }
{ "_id" : ObjectId("4e27baae7ff2440ba274d76b"), "id" : 4 }
{ "_id" : ObjectId("4e27baae7ff2440ba274d76c"), "id" : 5 }
{ "_id" : ObjectId("4e27baae7ff2440ba274d76d"), "id" : 6 }
{ "_id" : ObjectId("4e27baae7ff2440ba274d76e"), "id" : 7 }
{ "_id" : ObjectId("4e27baae7ff2440ba274d76f"), "id" : 8 }
{ "_id" : ObjectId("4e27baae7ff2440ba274d770"), "id" : 9 }
{ "_id" : ObjectId("4e27bf5c9033de6afd328581"), "id" : 10 }
> db.person.save({id : 11 })////锁定期间写被阻塞
-----------------
另开CMD
E:\mongodb\bin>mongo
MongoDB shell version: 1.8.2
connecting to: test
> use admin
switched to db admin
> db.$cmd.sys.unlock.findOne()
{ "ok" : 1, "info" : "unlock requested" }
------------------
> db.person.find()
{ "_id" : ObjectId("4e27baae7ff2440ba274d767"), "id" : 0 }
{ "_id" : ObjectId("4e27baae7ff2440ba274d768"), "id" : 1 }
{ "_id" : ObjectId("4e27baae7ff2440ba274d769"), "id" : 2 }
{ "_id" : ObjectId("4e27baae7ff2440ba274d76a"), "id" : 3 }
{ "_id" : ObjectId("4e27baae7ff2440ba274d76b"), "id" : 4 }
{ "_id" : ObjectId("4e27baae7ff2440ba274d76c"), "id" : 5 }
{ "_id" : ObjectId("4e27baae7ff2440ba274d76d"), "id" : 6 }
{ "_id" : ObjectId("4e27baae7ff2440ba274d76e"), "id" : 7 }
{ "_id" : ObjectId("4e27baae7ff2440ba274d76f"), "id" : 8 }
{ "_id" : ObjectId("4e27baae7ff2440ba274d770"), "id" : 9 }
{ "_id" : ObjectId("4e27bf5c9033de6afd328581"), "id" : 10 }
{ "_id" : ObjectId("4e27bfe99033de6afd328582"), "id" : 11 }

需要注意:两次锁定时第二次会等待第一次锁释放,锁定的时候当第一次有写操作时在没有解锁前所有的操作都不能进行。

5:备份与恢复

(完成person从27020备份然后还原到27017)

备份

E:\mongodb\bin>mongodump -h 10.53.139.138:27020 -d person2 -o E:\mongodb\bin\back
connected to: 10.53.139.138:27020
DATABASE: person2 to E:/mongodb/bin/back/person2
person2.person to E:/mongodb/bin/back/person2/person.bson
10 objects
person2.system.indexes to E:/mongodb/bin/back/person2/system.indexes.bson
1 objects

恢复

E:\mongodb\bin>mongo --port 27017
MongoDB shell version: 1.8.2
connecting to: 127.0.0.1:27017/test
> show dbs
admin (empty)
blog (empty)
local (empty)
person 0.03125GB
person1 0.03125GB
persons (empty)
> exit
bye
E:\mongodb\bin>mongorestore -h 10.53.139.138:27017 --directoryperdb E:\mongodb\b
in\back\person2
connected to: 10.53.139.138:27017
Thu Jul 21 14:36:10 E:/mongodb/bin/back/person2/person.bson
Thu Jul 21 14:36:10 going into namespace [person2.person]
Thu Jul 21 14:36:10 10 objects found
Thu Jul 21 14:36:10 E:/mongodb/bin/back/person2/system.indexes.bson
Thu Jul 21 14:36:10 going into namespace [person2.system.indexes]
Thu Jul 21 14:36:10 { name: "_id_", ns: "person2.person", key: { _id: 1 }, v: 0
}
Thu Jul 21 14:36:10 1 objects found
E:\mongodb\bin>mongo --port 27017
MongoDB shell version: 1.8.2
connecting to: 127.0.0.1:27017/test
> show dbs
admin (empty)
blog (empty)
local (empty)
person 0.03125GB
person1 0.03125GB
person2 0.03125GB
persons (empty)

公共参数:
--port arg    指定端口
-h arg    指定主机
-d arg    指定database
-c arg    指定collection
--dbpath arg    指定mongod的数据库文件所在路径

备份:
bsondump
命令用法:bsondump [options] <bson fileName>
特别参数:
--type arg 输出文件的格式,arg= json,debug在xp下不能用,没测试

mongodump
命令用法:mongodump [options]
特别参数:
-o arg 输出的"目录",不指定时,默认在执行命令的路径下创建dump目录导出
-q arg json query,此处可通过json查询,有选择性的导出数据
说明:
1.与mongorestore构成一对工具集,即由Mongodump导出的数据可由mongrestore恢复
2.mongodump可用于“热备份”
3.导出的数据是bson格式
性能:数据库中1g的数据导出后变成285M,大概8秒

备注
1. mogodump / mongorestore
这2命令将mongodb的数据dump为BSON格式,需要的时候可以恢复。
这种方式作为小的数据库还适用。但如果是sharding或者几百G数据以上的话
就几乎不可用了。因为BSON及其占用空间。
特别注意的是备份前执行db.runCommand({fsync : 1})将内存中的数据刷到文件中。
2. Slave Replication
这是最适合和可靠的,适合生产环境。MongoDb支持master+多个slave。因此可以很方便的起一个slave来进行备份。
但是需要注意的是如果数据量很大的话,如果是新建的slave,速度又没有保证的话,一定要调高 oplogSize 的大小,对于一个300G的数据库,
可以调到60G以上。这样避免同步到中间出现oplogSize不足等异常。
3. 关于增量热备份
对于某些热衷单独文件备份的同志,也可以考虑使用“增量热”备份的方式作为最后的屏障。
做法就是,最开始将某个slave暂时shutdown,然后将数据库文件复制到另一个目录作为增量备份的起点。
每次备份的时候,在这个目录上起一个slave, 使用–fastsync参数,同步完毕即可tar这个目录就可以了。
这种方式的一个缺点就是如果备份周期的过长的话,空间浪费会非常大,尤其是频繁删除的情况下,
目前1.6以前的版本对于删除的空间回收机制有bug。这个问题应该在1.6版本发布时候解决。
要想回收这些空间需要repairDatabase,速度比较慢,不如直接从头clone一个新的db了。(其实Repair的过程也就是先clone然后copy回来)。
综上所述, 最靠谱和安全的备份方式就是用mongodb自身的同步复制机制.
最经典也最小的生产环境是:
1 master + 2 slaves

6:导入与导出

导出(文件要预先建立)

E:\mongodb\bin>mongoexport -h 10.53.139.138 -d person -c person -o E:\mongodb\bin\aa.bson
connected to: 10.53.139.138
exported 14 records

导入

E:\mongodb\bin>mongo --port 27017
MongoDB shell version: 1.8.2
connecting to: 127.0.0.1:27017/test
> show dbs
admin (empty)
blog (empty)
local (empty)
person 0.03125GB
person1 0.03125GB
person2 0.03125GB
persons (empty)
> exit
bye
E:\mongodb\bin>mongoimport -h 10.53.139.138 --port 27017 -d person3 -c person --
file E:\mongodb\bin\aa.bson
connected to: 10.53.139.138:27017
imported 14 objects
E:\mongodb\bin>mongo --port 27017
MongoDB shell version: 1.8.2
connecting to: 127.0.0.1:27017/test
> show dbs
admin (empty)
blog (empty)
local (empty)
person 0.03125GB
person1 0.03125GB
person2 0.03125GB
person3 0.03125GB
persons (empty)

7:操作

插入

E:\mongodb\bin>mongo --port 27017
MongoDB shell version: 1.8.2
connecting to: 127.0.0.1:27017/test
> show dbs
admin (empty)
local (empty)
test (empty)
> use company
switched to db company
> u={name:"dabing",id:1}
{ "name" : "dabing", "id" : 1 }
> db.person.insert(u)
> db.person.find()
{ "_id" : ObjectId("4e27d1edb449d8dc5d763a57"), "name" : "dabing", "id" : 1 }
> u.id+=1
2
> db.person.save(u)
> db.person.find()
{ "_id" : ObjectId("4e27d1edb449d8dc5d763a57"), "name" : "dabing", "id" : 1 }
{ "_id" : ObjectId("4e27d228b449d8dc5d763a58"), "name" : "dabing", "id" : 2 }
> u=db.person.findOne({id:1})
{
"_id" : ObjectId("4e27d1edb449d8dc5d763a57"),
"name" : "dabing",
"id" : 1
}
> u.id+=2
3
> db.person.save(u)
> db.person.find()
{ "_id" : ObjectId("4e27d1edb449d8dc5d763a57"), "name" : "dabing", "id" : 3 }
{ "_id" : ObjectId("4e27d228b449d8dc5d763a58"), "name" : "dabing", "id" : 2 }

save() 可插入新文档,也可以更新(update)一个已有的文档

查询函数式有 find() 和 findOne(),前者返回一个迭代器 cursor,后者返回单个文档

查询

E:\mongodb\bin>mongo --port 27017
MongoDB shell version: 1.8.2
connecting to: 127.0.0.1:27017/test
> show dbs
admin (empty)
local (empty)
test (empty)
> show dbs
admin (empty)
local (empty)
test (empty)
> use company
switched to db company
> for (var i = 0; i < 10; i++) db.users.insert({name:"user" + i, age:20 + i, sex:i % 2})
> db.users.find({name:"user1"}) //select * from users where name = 'user1'
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5a"), "name" : "user1", "age" : 21, "sex" : 1 }
> db.users.find({name:"user1",age:1})
> db.users.find({name:"user1",age:21}) //select * from users where name = 'user1' and age = 21
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5a"), "name" : "user1", "age" : 21, "sex" : 1 }
> db.users.find({name:"user1",age:21},{name:1})
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5a"), "name" : "user1" }
> db.users.find({name:"user1",age:21},{name:1,age:1}) //select name,age from users where name = 'user1' and age = 21
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5a"), "name" : "user1", "age" : 21 }
> db.users.find().sort({age:1}) //select * from users order by age asc
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a59"), "name" : "user0", "age" : 20, "sex" : 0 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5a"), "name" : "user1", "age" : 21, "sex" : 1 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5b"), "name" : "user2", "age" : 22, "sex" : 0 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5c"), "name" : "user3", "age" : 23, "sex" : 1 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5d"), "name" : "user4", "age" : 24, "sex" : 0 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5e"), "name" : "user5", "age" : 25, "sex" : 1 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5f"), "name" : "user6", "age" : 26, "sex" : 0 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a60"), "name" : "user7", "age" : 27, "sex" : 1 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a61"), "name" : "user8", "age" : 28, "sex" : 0 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a62"), "name" : "user9", "age" : 29, "sex" : 1 }
> db.users.find().sort({age:-1})//select * from users order by age desc
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a62"), "name" : "user9", "age" : 29, "sex" : 1 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a61"), "name" : "user8", "age" : 28, "sex" : 0 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a60"), "name" : "user7", "age" : 27, "sex" : 1 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5f"), "name" : "user6", "age" : 26, "sex" : 0 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5e"), "name" : "user5", "age" : 25, "sex" : 1 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5d"), "name" : "user4", "age" : 24, "sex" : 0 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5c"), "name" : "user3", "age" : 23, "sex" : 1 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5b"), "name" : "user2", "age" : 22, "sex" : 0 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5a"), "name" : "user1", "age" : 21, "sex" : 1 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a59"), "name" : "user0", "age" : 20, "sex" : 0 }
> db.users.find().sort({sex:-1,age:-1}) //select * from users order by sex asce, age desc
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a62"), "name" : "user9", "age" : 29, "sex" : 1 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a60"), "name" : "user7", "age" : 27, "sex" : 1 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5e"), "name" : "user5", "age" : 25, "sex" : 1 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5c"), "name" : "user3", "age" : 23, "sex" : 1 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5a"), "name" : "user1", "age" : 21, "sex" : 1 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a61"), "name" : "user8", "age" : 28, "sex" : 0 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5f"), "name" : "user6", "age" : 26, "sex" : 0 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5d"), "name" : "user4", "age" : 24, "sex" : 0 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5b"), "name" : "user2", "age" : 22, "sex" : 0 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a59"), "name" : "user0", "age" : 20, "sex" : 0 }
> db.users.find().sort({sex:-1,age:-1}).skip(2).limit(3)//select * from users skip 2 limit 3
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5e"), "name" : "user5", "age" : 25, "sex" : 1 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5c"), "name" : "user3", "age" : 23, "sex" : 1 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5a"), "name" : "user1", "age" : 21, "sex" : 1 }
> db.users.find({sex:1, age:{$gt:23, $lt:28}})//select * from users where sex = 1 and age > 23 and age < 28
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5e"), "name" : "user5", "age" : 25, "sex" : 1 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a60"), "name" : "user7", "age" : 27, "sex" : 1 }
比较操作包括:$gt (>)、$lt (<)、$gte (>=)、$lte(<=)、$ne (!=)
> db.users.find({age:{$in:[23,26,32]}}) //select * from users where age in (23, 26, 32)
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5c"), "name" : "user3", "age" : 23, "sex" : 1 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5f"), "name" : "user6", "age" : 26, "sex" : 0 }
对应的操作符有 $nin (not in)
> db.users.find({age:{$gt:20}}).count()//select count(*) from users where age > 20
9
> db.users.find({$or:[{age:25}, {age:28}]})//select * from users where age = 25 or age = 28
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5e"), "name" : "user5", "age" : 25, "sex" : 1 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a61"), "name" : "user8", "age" : 28, "sex" : 0 }
> db.users.find({$or:[{age:{$lte:23}}, {age:{$gte:33}}]})//select * from users where age <= 23 or age >= 33
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a59"), "name" : "user0", "age" : 20, "sex" : 0 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5a"), "name" : "user1", "age" : 21, "sex" : 1 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5b"), "name" : "user2", "age" : 22, "sex" : 0 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5c"), "name" : "user3", "age" : 23, "sex" : 1 }

更新

E:\mongodb\bin>mongo --port 27017
MongoDB shell version: 1.8.2
connecting to: 127.0.0.1:27017/test
> show dbs
admin (empty)
company 0.03125GB
local (empty)
test (empty)
> db.users.find({name:"user1"})
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5a"), "name" : "user1", "age" : 100, "sex" : 0 }
//db.collection.update(criteria, objNew, upsert, mult)
//criteria: 需要被更新的条件表达式
//objNew: 更新表达式
//upsert: 如目标记录不存在,是否插入新文档。
//multi: 是否更新多个文档。
> db.users.update({name:"user1"}, {$set:{age:101, sex:0}})//update users set age = 101, sex = 0 where name = 'user1'
> db.users.find({name:"user1"})
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5a"), "name" : "user1", "age" : 101, "sex" : 0 }
> db.users.update({name:"user1"}, {$inc:{age:10}}, false, true)//update users set age = age + 10 where name = 'user1'
> db.users.find({name:"user1"})
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5a"), "name" : "user1", "age" : 111, "sex" : 0 }
> db.users.update({name:"user1"}, {$inc:{age:10}, $set:{sex:1}})//update users set age = age + 10, sex = 1 where name = 'user1'
> db.users.find({name:"user1"})
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5a"), "name" : "user1", "age" : 121, "sex" : 1 }

删除

> db.users.find()
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a59"), "name" : "user0", "age" : 20, "sex" : 0 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5a"), "name" : "user1", "age" : 121, "sex" : 1 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5b"), "name" : "user2", "age" : 22, "sex" : 0 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5c"), "name" : "user3", "age" : 23, "sex" : 1 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5d"), "name" : "user4", "age" : 24, "sex" : 0 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5e"), "name" : "user5", "age" : 25, "sex" : 1 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5f"), "name" : "user6", "age" : 26, "sex" : 0 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a60"), "name" : "user7", "age" : 27, "sex" : 1 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a61"), "name" : "user8", "age" : 28, "sex" : 0 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a62"), "name" : "user9", "age" : 29, "sex" : 1 }
> db.users.remove({name:"user3"})
> db.users.find()
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a59"), "name" : "user0", "age" : 20, "sex" : 0 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5a"), "name" : "user1", "age" : 121, "sex" : 1 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5b"), "name" : "user2", "age" : 22, "sex" : 0 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5d"), "name" : "user4", "age" : 24, "sex" : 0 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5e"), "name" : "user5", "age" : 25, "sex" : 1 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a5f"), "name" : "user6", "age" : 26, "sex" : 0 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a60"), "name" : "user7", "age" : 27, "sex" : 1 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a61"), "name" : "user8", "age" : 28, "sex" : 0 }
{ "_id" : ObjectId("4e27d3e2b449d8dc5d763a62"), "name" : "user9", "age" : 29, "sex" : 1 }
> db.users.remove()
> db.users.find()

MapReduce

E:\mongodb\bin>mongo --port 27017
MongoDB shell version: 1.8.2
connecting to: 127.0.0.1:27017/test
> use blog
switched to db blog
>for (var i = 0; i < 1000; i++) {
... var u = { name : "user" + i, age : i % 40 + 1, sex : i % 2 };
... db.users.insert(u);
... }
> db.users.ensureIndex({name:1})
> db.users.ensureIndex({age:1})
//相当于select count(*) value,age from users group by age
> m = function() { emit(this.age, 1) }
function () {
emit(this.age, 1);
}
> r = function(key, values) {
... ... var x = 0;
... ... values.forEach(function(v) { x += v });//这里可以执行批量更新操作eg
... ... return x;
... ... }
------------------//批量更新例子
r = function(key, values) {
... update = function(v) {
... db.users.update({_id:key}, {$inc:{age:1}}, false, false);
... }
... values.forEach(update);
... return key;
... }
mapreduce: 要操作的目标集合。
map: 映射函数 (生成键值对序列,作为 reduce 函数参数)。
reduce: 统计函数。
query: 目标记录过滤。
sort: 目标记录排序。
limit: 限制目标记录数量。
out: 统计结果存放集合 (不指定则使用临时集合,在客户端断开后自动删除)。
keeptemp: 是否保留临时集合。
finalize: 最终处理函数 (对 reduce 返回结果进行最终整理后存入结果集合)。
scope: 向 map、reduce、finalize 导入外部变量。
verbose: 显示详细的时间统计信息。
--------------------
function (key, values) {
var x = 0;
values.forEach(function (v) {x += v;});
return x;
}
> res = db.users.mapReduce(m, r,{out:"res"});
{
"result" : "res",
"timeMillis" : 62,
"counts" : {
"input" : 1000,
"emit" : 1000,
"output" : 40
},
"ok" : 1,
}
> db.res.find()
{ "_id" : 1, "value" : 25 }
{ "_id" : 2, "value" : 25 }
{ "_id" : 3, "value" : 25 }
{ "_id" : 4, "value" : 25 }
{ "_id" : 5, "value" : 25 }
{ "_id" : 6, "value" : 25 }
{ "_id" : 7, "value" : 25 }
{ "_id" : 8, "value" : 25 }
{ "_id" : 9, "value" : 25 }
{ "_id" : 10, "value" : 25 }
{ "_id" : 11, "value" : 25 }
{ "_id" : 12, "value" : 25 }
{ "_id" : 13, "value" : 25 }
{ "_id" : 14, "value" : 25 }
{ "_id" : 15, "value" : 25 }
{ "_id" : 16, "value" : 25 }
{ "_id" : 17, "value" : 25 }
{ "_id" : 18, "value" : 25 }
{ "_id" : 19, "value" : 25 }
{ "_id" : 20, "value" : 25 }
has more
//可以进一步处理
> f = function(key, value) { return {age:key, count:value}; }
function (key, value) {
return {age:key, count:value};
}
//res = db.users.mapReduce(m, r,{out:"res",finalize:f,query:{age:{$lt:10}}, sort:{name:1}, limit:5}});
> res = db.users.mapReduce(m, r,{out:"res",finalize:f});
{
"result" : "res",
"timeMillis" : 31,
"counts" : {
"input" : 1000,
"emit" : 1000,
"output" : 40
},
"ok" : 1,
}
> db.res.find()
{ "_id" : 1, "value" : { "age" : 1, "count" : 25 } }
{ "_id" : 2, "value" : { "age" : 2, "count" : 25 } }
{ "_id" : 3, "value" : { "age" : 3, "count" : 25 } }
{ "_id" : 4, "value" : { "age" : 4, "count" : 25 } }
{ "_id" : 5, "value" : { "age" : 5, "count" : 25 } }
{ "_id" : 6, "value" : { "age" : 6, "count" : 25 } }
{ "_id" : 7, "value" : { "age" : 7, "count" : 25 } }
{ "_id" : 8, "value" : { "age" : 8, "count" : 25 } }
{ "_id" : 9, "value" : { "age" : 9, "count" : 25 } }
{ "_id" : 10, "value" : { "age" : 10, "count" : 25 } }
{ "_id" : 11, "value" : { "age" : 11, "count" : 25 } }
{ "_id" : 12, "value" : { "age" : 12, "count" : 25 } }
{ "_id" : 13, "value" : { "age" : 13, "count" : 25 } }
{ "_id" : 14, "value" : { "age" : 14, "count" : 25 } }
{ "_id" : 15, "value" : { "age" : 15, "count" : 25 } }
{ "_id" : 16, "value" : { "age" : 16, "count" : 25 } }
{ "_id" : 17, "value" : { "age" : 17, "count" : 25 } }
{ "_id" : 18, "value" : { "age" : 18, "count" : 25 } }
{ "_id" : 19, "value" : { "age" : 19, "count" : 25 } }
{ "_id" : 20, "value" : { "age" : 20, "count" : 25 } }
has more
>

其他操作

> u = db.users.findOne({"im.qq":12345})
{
"_id" : ObjectId("4e27dc01df0c628545d11eac"),
"name" : "user1",
"age" : 15,
"address" : [
"address1",
"address2"
],
"im" : {
"msn" : "user1@hotmail.com",
"qq" : 12345
}
}
> u = db.users.find({"im.qq":{$exists:true}}, {"im.qq":1}) //可以通过 $exists 判断某个字段是否存在
{ "_id" : ObjectId("4e27dc01df0c628545d11eac"), "im" : { "qq" : 12345 } }
> db.users.insert({name:"user3", data:[1,2,3,4,5,6,7]})
> db.users.insert({name:"user4", data:[1,2,3]})
> db.users.find({data:{$all:[2,3,4]}}) //$all: 判断数组属性是否包含全部条件。
{ "_id" : ObjectId("4e27dcc1df0c628545d11eae"), "name" : "user3", "data" : [ 1,2, 3, 4, 5, 6, 7 ] }
注意和 $in 的区别。$in 是检查目标属性值是条件表达式中的一员,而 $all 则要求属性值包含全部条件元素。
> db.users.find({data:{$size:3}})//$size: 匹配数组属性元素数量
{ "_id" : ObjectId("4e27dcc6df0c628545d11eaf"), "name" : "user4", "data" : [ 1,2, 3 ] }
> db.users.find({data:{$type:1}})//$type: 判断属性类型。
{ "_id" : ObjectId("4e27dcc1df0c628545d11eae"), "name" : "user3", "data" : [ 1,2, 3, 4, 5, 6, 7 ] }
{ "_id" : ObjectId("4e27dcc6df0c628545d11eaf"), "name" : "user4", "data" : [ 1,2, 3 ] }
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
> db.users.find({name:/user[135]/i}, {name:1})//使用正则表达式进行查询。
{ "_id" : ObjectId("4e27dcc1df0c628545d11eae"), "name" : "user3" }
i: 忽略大小写。
m: 默认为单行处理,此标记表示多行。
x: 扩展。
> db.users.find({address:"abc"})//数组属性元素值匹配
{ "_id" : ObjectId("4e27de60df0c628545d11eb0"), "name" : "user1", "age" : 15, "address" : [ { "a" : 1 }, { "b" : 1 }, 3, "abc" ] }
> db.users.find({address:{$elemMatch:{a:1, b:{$gt:5}}}})
//{data:"abc"} 仅简单匹配数组属性是否包含该元素。$elemMatch 则可以处理更复杂的元素查找条件。当然也可以写成如下方式。{elemMatch没有找出}
//还可以直接使用序号进行操作
> db.users.find({"address.a":1, "address.b":{$gt:5}})
{ "_id" : ObjectId("4e27de60df0c628545d11eb0"), "name" : "user1", "age" : 15, "address" : [ { "a" : 1 }, { "b" : 10 }, 3, "abc" ] }
> db.users.find({"address.2":3})
{ "_id" : ObjectId("4e27de60df0c628545d11eb0"), "name" : "user1", "age" : 15, "address" : [ { "a" : 1 }, { "b" : 10 }, 3, "abc" ] }
> db.users.find({name:{$not:/user3/}}, {name:1})//$not: 取反,表示返回条件不成立的文档。
{ "_id" : ObjectId("4e27de60df0c628545d11eb0"), "name" : "user1" }
{ "_id" : ObjectId("4e27e1ebdf0c628545d11eb1"), "name" : "user0" }
{ "_id" : ObjectId("4e27e1ebdf0c628545d11eb2"), "name" : "user1" }
{ "_id" : ObjectId("4e27e1ebdf0c628545d11eb3"), "name" : "user2" }
{ "_id" : ObjectId("4e27e1ebdf0c628545d11eb5"), "name" : "user4" }
{ "_id" : ObjectId("4e27e1ebdf0c628545d11eb6"), "name" : "user5" }
{ "_id" : ObjectId("4e27e1ebdf0c628545d11eb7"), "name" : "user6" }
{ "_id" : ObjectId("4e27e1ebdf0c628545d11eb8"), "name" : "user7" }
{ "_id" : ObjectId("4e27e1ebdf0c628545d11eb9"), "name" : "user8" }
{ "_id" : ObjectId("4e27e1ebdf0c628545d11eba"), "name" : "user9" }
> db.users.find({name:"user1"})
{ "_id" : ObjectId("4e27de60df0c628545d11eb0"), "name" : "user1", "age" : 15, "address" : [ { "a" : 1 }, { "b" : 10 }, 3, "abc" ] }
{ "_id" : ObjectId("4e27e1ebdf0c628545d11eb2"), "name" : "user1", "age" : 21, "sex" : 1 }
> db.users.update({name:"user1"}, {$unset:{address:1, im:1}})//$unset: 和 $set 相反,表示移除文档属性
> db.users.find({name:"user1"})
{ "_id" : ObjectId("4e27de60df0c628545d11eb0"), "age" : 15, "name" : "user1" }
{ "_id" : ObjectId("4e27e1ebdf0c628545d11eb2"), "name" : "user1", "age" : 21, "sex" : 1 }
> u = db.users.find({name:"user2"})
{ "_id" : ObjectId("4e27e1ebdf0c628545d11eb3"), "name" : "user2", "age" : 22, "sex" : 0 }
> db.users.update({name:"user2"}, {$push:{data:1}}) //$push: 和 $ pushAll 都是向数组属性添加元素
> u = db.users.find({name:"user2"})
{ "_id" : ObjectId("4e27e1ebdf0c628545d11eb3"), "age" : 22, "data" : [ 1 ], "name" : "user2", "sex" : 0 }
> db.users.update({name:"user2"}, {$pushAll:{data:[2,3,4,5]}})
> u = db.users.find({name:"user2"})
{ "_id" : ObjectId("4e27e1ebdf0c628545d11eb3"), "age" : 22, "data" : [ 1, 2, 3,4, 5 ], "name" : "user2", "sex" : 0 }
> u = db.users.find({name:"user3"})
{ "_id" : ObjectId("4e27e1ebdf0c628545d11eb4"), "name" : "user3", "age" : 23, "sex" : 1 }
> db.users.update({name:"user3"}, {$addToSet:{data:1}}) // $addToSet: 和 $push 类似,不过仅在该元素不存在时才添加 (Set 表示不重复元素集合)
> u = db.users.find({name:"user3"})
{ "_id" : ObjectId("4e27e1ebdf0c628545d11eb4"), "age" : 23, "data" : [ 1 ], "name" : "user3", "sex" : 1 }
> db.users.update({name:"user3"}, {$addToSet:{data:1}})
> u = db.users.find({name:"user3"})
{ "_id" : ObjectId("4e27e1ebdf0c628545d11eb4"), "age" : 23, "data" : [ 1 ], "name" : "user3", "sex" : 1 }
> db.users.update({name:"user3"}, {$push:{data:1}})
> u = db.users.find({name:"user3"})
{ "_id" : ObjectId("4e27e1ebdf0c628545d11eb4"), "age" : 23, "data" : [ 1, 1 ], "name" : "user3", "sex" : 1 }
> db.users.update({name:"user4"}, {$addToSet:{data:{$each:[1,2,3,4]}}})//要添加多个元素,使用 $each
> u = db.users.find({name:"user4"})
{ "_id" : ObjectId("4e27e1ebdf0c628545d11eb5"), "age" : 24, "data" : [ 1, 2, 3,4 ], "name" : "user4", "sex" : 0 }
> db.users.find({name:"user4"})
{ "_id" : ObjectId("4e27e1ebdf0c628545d11eb5"), "age" : 24, "data" : [ 1, 2, 3,4 ], "name" : "user4", "sex" : 0 }
> db.users.update({name:"user4"}, {$pop:{data:1}}) //$pop: 移除数组属性的元素,$pull 按值移除,$pullAll 移除所有符合提交的元素
> db.users.find({name:"user4"})
{ "_id" : ObjectId("4e27e1ebdf0c628545d11eb5"), "age" : 24, "data" : [ 1, 2, 3 ], "name" : "user4", "sex" : 0 }
> db.users.update({name:"user4"}, {$pop:{data:-1}})
> db.users.find({name:"user4"})
{ "_id" : ObjectId("4e27e1ebdf0c628545d11eb5"), "age" : 24, "data" : [ 2, 3 ], "name" : "user4", "sex" : 0 }
> db.users.update({name:"user4"}, {$pull:{data:2}})//移除全部 2
> db.users.find({name:"user4"})
{ "_id" : ObjectId("4e27e1ebdf0c628545d11eb5"), "age" : 24, "data" : [ 3 ], "name" : "user4", "sex" : 0 }
> db.users.find({name:"user2"})
{ "_id" : ObjectId("4e27e1ebdf0c628545d11eb3"), "age" : 22, "data" : [ 1, 2, 3,4, 5 ], "name" : "user2", "sex" : 0 }
> db.users.update({name:"user2"}, {$pullAll:{data:[2,3,6]}})
> db.users.find({name:"user2"})
{ "_id" : ObjectId("4e27e1ebdf0c628545d11eb3"), "age" : 22, "data" : [ 1, 4, 5 ], "name" : "user2", "sex" : 0 }
> db.dropDatabase()
{ "dropped" : "company", "ok" : 1 }
> for (var i = 0; i < 10; i++) db.users.insert({name:"user"+i, age:i})
> db.users.find()//$where: 用 JS 代码来代替有些丑陋的 $lt、$gt
{ "_id" : ObjectId("4e27e3b4df0c628545d11ebb"), "name" : "user0", "age" : 0 }
{ "_id" : ObjectId("4e27e3b4df0c628545d11ebc"), "name" : "user1", "age" : 1 }
{ "_id" : ObjectId("4e27e3b4df0c628545d11ebd"), "name" : "user2", "age" : 2 }
{ "_id" : ObjectId("4e27e3b4df0c628545d11ebe"), "name" : "user3", "age" : 3 }
{ "_id" : ObjectId("4e27e3b4df0c628545d11ebf"), "name" : "user4", "age" : 4 }
{ "_id" : ObjectId("4e27e3b4df0c628545d11ec0"), "name" : "user5", "age" : 5 }
{ "_id" : ObjectId("4e27e3b4df0c628545d11ec1"), "name" : "user6", "age" : 6 }
{ "_id" : ObjectId("4e27e3b4df0c628545d11ec2"), "name" : "user7", "age" : 7 }
{ "_id" : ObjectId("4e27e3b4df0c628545d11ec3"), "name" : "user8", "age" : 8 }
{ "_id" : ObjectId("4e27e3b4df0c628545d11ec4"), "name" : "user9", "age" : 9 }
> db.users.find({$where:"this.age > 7 || this.age < 3"})
{ "_id" : ObjectId("4e27e3b4df0c628545d11ebb"), "name" : "user0", "age" : 0 }
{ "_id" : ObjectId("4e27e3b4df0c628545d11ebc"), "name" : "user1", "age" : 1 }
{ "_id" : ObjectId("4e27e3b4df0c628545d11ebd"), "name" : "user2", "age" : 2 }
{ "_id" : ObjectId("4e27e3b4df0c628545d11ec3"), "name" : "user8", "age" : 8 }
{ "_id" : ObjectId("4e27e3b4df0c628545d11ec4"), "name" : "user9", "age" : 9 }
> db.users.find("this.age > 7 || this.age < 3")
{ "_id" : ObjectId("4e27e3b4df0c628545d11ebb"), "name" : "user0", "age" : 0 }
{ "_id" : ObjectId("4e27e3b4df0c628545d11ebc"), "name" : "user1", "age" : 1 }
{ "_id" : ObjectId("4e27e3b4df0c628545d11ebd"), "name" : "user2", "age" : 2 }
{ "_id" : ObjectId("4e27e3b4df0c628545d11ec3"), "name" : "user8", "age" : 8 }
{ "_id" : ObjectId("4e27e3b4df0c628545d11ec4"), "name" : "user9", "age" : 9 }
> db.users.find({$where: function(){ return this.age > 7 || this.age < 3;}})
{ "_id" : ObjectId("4e27e3b4df0c628545d11ebb"), "name" : "user0", "age" : 0 }
{ "_id" : ObjectId("4e27e3b4df0c628545d11ebc"), "name" : "user1", "age" : 1 }
{ "_id" : ObjectId("4e27e3b4df0c628545d11ebd"), "name" : "user2", "age" : 2 }
{ "_id" : ObjectId("4e27e3b4df0c628545d11ec3"), "name" : "user8", "age" : 8 }
{ "_id" : ObjectId("4e27e3b4df0c628545d11ec4"), "name" : "user9", "age" : 9 }

8:索引

> for (var i = 0; i < 30; i++) {
... u = { name : "user" + i,
... age : 20 + i,
... contact : {
... address : ["address1_" + i, "address2_" + i],
... postcode : 100000 + i,
... }
... };
... db.users.insert(u);
... }
//使用 ensureIndex 创建索引,dropIndex() 删除索引,dropIndexes() 删除全部索引(不包括 _id 等系统索引)。
> db.users.ensureIndex({name:1})
> db.users.ensureIndex({age:1})
> db.system.indexes.find()
{ "name" : "_id_", "ns" : "blog.users", "key" : { "_id" : 1 } }
{ "_id" : ObjectId("4c4a...b798"), "ns" : "blog.users", "key" : { "name" : 1 }, "name" : "name_1" }
{ "_id" : ObjectId("4c4a...b799"), "ns" : "blog.users", "key" : { "age" : 1 }, "name" : "age_1" }
> db.users.dropIndex({age:1})
{ "nIndexesWas" : 3, "ok" : true }
> db.users.dropIndexes()
{
"nIndexesWas" : 2,
"msg" : "non-_id indexes dropped for collection",
"ok" : true
}
> db.system.indexes.find()
{ "name" : "_id_", "ns" : "blog.users", "key" : { "_id" : 1 } }
//reIndex 则是重建索引
> db.users.ensureIndex({name:1})
> db.users.ensureIndex({age:1})
> db.system.indexes.find()
{ "name" : "_id_", "ns" : "blog.users", "key" : { "_id" : 1 } }
{ "_id" : ObjectId("4c4a...b82a"), "ns" : "blog.users", "key" : { "name" : 1 }, "name" : "name_1" }
{ "_id" : ObjectId("4c4a...b82b"), "ns" : "blog.users", "key" : { "age" : 1 }, "name" : "age_1" }
> db.users.reIndex()
{
"nIndexesWas" : 3,
"msg" : "indexes dropped for collection",
"ok" : 1,
"nIndexes" : 3,
"indexes" : [
{
"name" : "_id_",
"ns" : "blog.users",
"key" : {
"_id" : 1
}
},
{
"_id" : ObjectId("4c4a...b82a"),
"ns" : "blog.users",
"key" : {
"name" : 1
},
"name" : "name_1"
},
{
"_id" : ObjectId("4c4a...b82b"),
"ns" : "blog.users",
"key" : {
"age" : 1
},
"name" : "age_1"
}
],
"ok" : 1
}
> db.users.dropIndexes()
{
"nIndexesWas" : 3,
"msg" : "non-_id indexes dropped for collection",
"ok" : true
}
//当系统已有大量数据时,创建索引就是个非常耗时的活,我们可以在后台执行。
> db.users.ensureIndex({name:1}, {backgroud:true})
> db.users.reIndex({backgroud:true})
{
"nIndexesWas" : 2,
"msg" : "indexes dropped for collection",
"ok" : 1,
"nIndexes" : 2,
"indexes" : [
{
"name" : "_id_",
"ns" : "blog.users",
"key" : {
"_id" : 1
}
},
{
"_id" : ObjectId("4c4a...b79c"),
"ns" : "blog.users",
"key" : {
"name" : 1
},
"name" : "name_1",
"backgroud" : true
}
],
"ok" : 1
}
//MongoDB 提供了一个 explain 命令让我们获知系统如何处理查询请求。
> db.users.ensureIndex({name:1})
> db.users.ensureIndex({age:1})
> db.users.find({age:{$gt:45}}, {name:1, age:1})
{ "_id" : ObjectId("4c4a8edeeb257107735eb826"), "name" : "user26", "age" : 46 }
{ "_id" : ObjectId("4c4a8edeeb257107735eb827"), "name" : "user27", "age" : 47 }
{ "_id" : ObjectId("4c4a8edeeb257107735eb828"), "name" : "user28", "age" : 48 }
{ "_id" : ObjectId("4c4a8edeeb257107735eb829"), "name" : "user29", "age" : 49 }
> db.users.find({age:{$gt:45}}, {name:1, age:1}).explain()
{
"cursor" : "BtreeCursor age_1",
"nscanned" : 5,
"nscannedObjects" : 4,
"n" : 4,
"millis" : 0,
"indexBounds" : [
[
{
"age" : 45
},
{
"age" : 1.7976931348623157e+308
}
]
]
}
cursor: 返回游标类型(BasicCursor 或 BtreeCursor)。
nscanned: 被扫描的文档数量。
n: 返回的文档数量。
millis: 耗时(毫秒)。
indexBounds: 所使用的索引。
//我们可以创建深层索引,甚至直接用文档(sub-document)作为索引键。
> db.users.ensureIndex({"contact.postcode":1})
> db.users.find({"contact.postcode":{$lt:100009}}, {name:1, "contact.postcode":1})
{ "_id" : ObjectId("4c4a8edeeb257107735eb80c"), "name" : "user0", "contact" : { "postcode" : 100000 } }
{ "_id" : ObjectId("4c4a8edeeb257107735eb80d"), "name" : "user1", "contact" : { "postcode" : 100001 } }
{ "_id" : ObjectId("4c4a8edeeb257107735eb80e"), "name" : "user2", "contact" : { "postcode" : 100002 } }
{ "_id" : ObjectId("4c4a8edeeb257107735eb80f"), "name" : "user3", "contact" : { "postcode" : 100003 } }
{ "_id" : ObjectId("4c4a8edeeb257107735eb810"), "name" : "user4", "contact" : { "postcode" : 100004 } }
{ "_id" : ObjectId("4c4a8edeeb257107735eb811"), "name" : "user5", "contact" : { "postcode" : 100005 } }
{ "_id" : ObjectId("4c4a8edeeb257107735eb812"), "name" : "user6", "contact" : { "postcode" : 100006 } }
{ "_id" : ObjectId("4c4a8edeeb257107735eb813"), "name" : "user7", "contact" : { "postcode" : 100007 } }
{ "_id" : ObjectId("4c4a8edeeb257107735eb814"), "name" : "user8", "contact" : { "postcode" : 100008 } }
> db.users.find({"contact.postcode":{$lt:100009}}, {name:1, "contact.postcode":1}).explain()
{
"cursor" : "BtreeCursor contact.postcode_1",
"nscanned" : 10,
"nscannedObjects" : 9,
"n" : 9,
"millis" : 0,
"indexBounds" : [
[
{
"contact.postcode" : -1.7976931348623157e+308
},
{
"contact.postcode" : 100009
}
]
]
}
> db.users.dropIndex({"contact.postcode":1})
{ "nIndexesWas" : 4, "ok" : 1 }
> db.users.ensureIndex({contact:1})
> db.system.indexes.find()
{ "name" : "_id_", "ns" : "blog.users", "key" : { "_id" : 1 }, "v" : 0 }
{ "_id" : ObjectId("4e27eb604855eaada94c711f"), "ns" : "blog.users", "key" : { "name" : 1 }, "name" : "name_1", "backgroud" : true, "v" : 0 }
{ "_id" : ObjectId("4e27eb7c4855eaada94c7121"), "ns" : "blog.users", "key" : { "age" : 1 }, "name" : "age_1", "v" : 0 }
{ "_id" : ObjectId("4e27ebc64855eaada94c7123"), "ns" : "blog.users", "key" : { "contact" : 1 }, "name" : "contact_1", "v" : 0 }
> db.users.find({contact:{postcode:{$lt:100009}}}).explain()
{
"cursor" : "BtreeCursor contact_1",
"nscanned" : 0,
"nscannedObjects" : 0,
"n" : 0,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"contact" : [
[
{
"postcode" : {
"$lt" : 100009
}
},
{
"postcode" : {
"$lt" : 100009
}
}
]
]
}
}
> db.users.find({"contact.postcode":{$lt:100009}}).explain()
{
"cursor" : "BasicCursor",
"nscanned" : 30,
"nscannedObjects" : 30,
"n" : 9,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
}
}
> db.users.find({contact:{address:"address2_23"}}).explain()
{
"cursor" : "BtreeCursor contact_1",
"nscanned" : 0,
"nscannedObjects" : 0,
"n" : 0,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"contact" : [
[
{
"address" : "address2_23"
},
{
"address" : "address2_23"
}
]
]
}
}
> db.users.find({"contact.address":"address2_23"}).explain()
{
"cursor" : "BasicCursor",
"nscanned" : 30,
"nscannedObjects" : 30,
"n" : 1,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
}
}
//创建复合索引也很简单
> db.users.ensureIndex({name:1, age:-1})
> db.system.indexes.find()
{ "name" : "_id_", "ns" : "blog.users", "key" : { "_id" : 1 }, "v" : 0 }
{ "_id" : ObjectId("4e27eb604855eaada94c711f"), "ns" : "blog.users", "key" : { "name" : 1 }, "name" : "name_1", "backgroud" : true, "v" : 0 }
{ "_id" : ObjectId("4e27eb7c4855eaada94c7121"), "ns" : "blog.users", "key" : { "age" : 1 }, "name" : "age_1", "v" : 0 }
{ "_id" : ObjectId("4e27ebc64855eaada94c7123"), "ns" : "blog.users", "key" : { "contact" : 1 }, "name" : "contact_1", "v" : 0 }
{ "_id" : ObjectId("4e27ec0a4855eaada94c7124"), "ns" : "blog.users", "key" : { "name" : 1, "age" : -1 }, "name" : "name_1_age_-1", "v" : 0 }
> db.users.find({age:{$lt:25}, name:"user2"}, {name:1, age:1})
{ "_id" : ObjectId("4e27eac34855eaada94c70fe"), "name" : "user2", "age" : 22 }
> db.users.find({age:{$lt:25}, name:"user2"}, {name:1, age:1}).explain()
{
"cursor" : "BtreeCursor name_1_age_-1",
"nscanned" : 1,
"nscannedObjects" : 1,
"n" : 1,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"name" : [
[
"user2",
"user2"
]
],
"age" : [
[
25,
-1.7976931348623157e+308
]
]
}
}
//复合索引同样可用于局部属性的搜索,但必须依照索引字段顺序。比如创建索引字段顺序 "a,b,c",那么仅对 "a,b,c"、"a,b"、"a" 查询有效,而对 "b,c" 之类的组合无效。
> db.users.dropIndex({name:1})
{ "nIndexesWas" : 5, "ok" : 1 }
> db.users.dropIndex({name:1})
{ "errmsg" : "index not found", "ok" : 0 }
> db.users.dropIndex({age:1})
{ "nIndexesWas" : 4, "ok" : 1 }
> db.users.dropIndex({contact:1})
{ "nIndexesWas" : 3, "ok" : 1 }
> db.system.indexes.find()
{ "name" : "_id_", "ns" : "blog.users", "key" : { "_id" : 1 }, "v" : 0 }
{ "_id" : ObjectId("4e27ec0a4855eaada94c7124"), "ns" : "blog.users", "key" : { "name" : 1, "age" : -1 }, "name" : "name_1_age_-1", "v" : 0 }
> db.users.find({name:"user12"}).explain()
{
"cursor" : "BtreeCursor name_1_age_-1",
"nscanned" : 1,
"nscannedObjects" : 1,
"n" : 1,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"name" : [
[
"user12",
"user12"
]
],
"age" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
]
}
}
> db.users.find({age:18}).explain()
{
"cursor" : "BasicCursor",
"nscanned" : 30,
"nscannedObjects" : 30,
"n" : 0,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
}
}
//只需在 ensureIndex 命令中指定 unique 即可创建唯一索引。
> db.users.ensureIndex({name:1}, {unique:true})
> db.system.indexes.find()
{ "name" : "_id_", "ns" : "blog.users", "key" : { "_id" : 1 }, "v" : 0 }
{ "_id" : ObjectId("4e27ec0a4855eaada94c7124"), "ns" : "blog.users", "key" : { "name" : 1, "age" : -1 }, "name" : "name_1_age_-1", "v" : 0 }
{ "_id" : ObjectId("4e27ec794855eaada94c7125"), "ns" : "blog.users", "key" : { "name" : 1 }, "name" : "name_1", "unique" : true, "v" : 0 }
> db.users.insert({name:"user1"})
E11000 duplicate key error index: blog.users.$name_1 dup key: { : "user1" }
//如果创建唯一索引前已经有重复文档,那么可以用 dropDups 删除多余的数据。
> db.users.dropIndexes()
{
"nIndexesWas" : 3,
"msg" : "non-_id indexes dropped for collection",
"ok" : 1
}
> db.users.insert({name:"user1"})
> db.users.find({name:"user1"}, {name:1})
{ "_id" : ObjectId("4e27eac34855eaada94c70fd"), "name" : "user1" }
{ "_id" : ObjectId("4e27ec9f4855eaada94c7127"), "name" : "user1" }
> db.users.ensureIndex({name:1}, {unique:true, dropDups:true})
E11000 duplicate key error index: blog.users.$name_1 dup key: { : "user1" }
> db.users.find({name:"user1"}, {name:1})
{ "_id" : ObjectId("4e27eac34855eaada94c70fd"), "name" : "user1" }
//对于数组类型属性,会自动索引全部数组元素
> db.users.dropIndexes()
{
"nIndexesWas" : 2,
"msg" : "non-_id indexes dropped for collection",
"ok" : 1
}
> db.users.ensureIndex({"contact.address":1})
> db.users.find({"contact.address":"address2_13"}).explain()
{
"cursor" : "BtreeCursor contact.address_1",
"nscanned" : 1,
"nscannedObjects" : 1,
"n" : 1,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : true,
"indexOnly" : false,
"indexBounds" : {
"contact.address" : [
[
"address2_13",
"address2_13"
]
]
}
}
//hint 命令可以强制使用某个索引
> db.users.dropIndexes()
{
"nIndexesWas" : 2,
"msg" : "non-_id indexes dropped for collection",
"ok" : 1
}
> db.users.ensureIndex({name:1, age:1})
> db.users.find({age:{$lt:30}}).explain()
{
"cursor" : "BasicCursor",
"nscanned" : 30,
"nscannedObjects" : 30,
"n" : 10,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
}
}
> db.users.find({age:{$lt:30}}).hint({name:1, age:1}).explain()
{
"cursor" : "BtreeCursor name_1_age_1",
"nscanned" : 30,
"nscannedObjects" : 10,
"n" : 10,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"name" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"age" : [
[
-1.7976931348623157e+308,
30
]
]
}
}
//MongoDB 会将索引数据载入内存,以提高查询速度。我们可以用 totalIndexSize 获取全部索引数据大小
> db.users.totalIndexSize()
16384

9:优化

//MongoDB 自带 Profiler,可以非常方便地记录下所有耗时过长操作,以便于调优。
> db.setProfilingLevel(n)
n:
0: Off;
1: Log Slow Operations;
2: Log All Operations.
通常我们只关心 Slow Operation,Level 1 默认记录 >100ms 的操作,当然我们也可以自己调整 "db.setProfilingLevel(2, 300)"。
Profiler 信息保存在 system.profile (Capped Collection) 中。
> db.setProfilingLevel(1)
{ "was" : 1, "slowms" : 100, "ok" : 1 }
> db.users.find().sort({age:-1}).limit(10000)
{ "_id" : ObjectId("4e27f34e256a7f5699394589"), "name" : "user2583248", "age" :2583268, "sex" : 0 }
{ "_id" : ObjectId("4e27f34e256a7f5699394588"), "name" : "user2583247", "age" :2583267, "sex" : 1 }
{ "_id" : ObjectId("4e27f34e256a7f5699394587"), "name" : "user2583246", "age" :2583266, "sex" : 0 }
{ "_id" : ObjectId("4e27f34e256a7f5699394586"), "name" : "user2583245", "age" :2583265, "sex" : 1 }
{ "_id" : ObjectId("4e27f34e256a7f5699394585"), "name" : "user2583244", "age" :2583264, "sex" : 0 }
{ "_id" : ObjectId("4e27f34e256a7f5699394584"), "name" : "user2583243", "age" :2583263, "sex" : 1 }
{ "_id" : ObjectId("4e27f34e256a7f5699394583"), "name" : "user2583242", "age" :2583262, "sex" : 0 }
{ "_id" : ObjectId("4e27f34e256a7f5699394582"), "name" : "user2583241", "age" :2583261, "sex" : 1 }
{ "_id" : ObjectId("4e27f34e256a7f5699394581"), "name" : "user2583240", "age" :2583260, "sex" : 0 }
{ "_id" : ObjectId("4e27f34e256a7f5699394580"), "name" : "user2583239", "age" :2583259, "sex" : 1 }
{ "_id" : ObjectId("4e27f34e256a7f569939457f"), "name" : "user2583238", "age" :2583258, "sex" : 0 }
{ "_id" : ObjectId("4e27f34e256a7f569939457e"), "name" : "user2583237", "age" :2583257, "sex" : 1 }
{ "_id" : ObjectId("4e27f34e256a7f569939457d"), "name" : "user2583236", "age" :2583256, "sex" : 0 }
{ "_id" : ObjectId("4e27f34e256a7f569939457c"), "name" : "user2583235", "age" :2583255, "sex" : 1 }
{ "_id" : ObjectId("4e27f34e256a7f569939457b"), "name" : "user2583234", "age" :2583254, "sex" : 0 }
{ "_id" : ObjectId("4e27f34e256a7f569939457a"), "name" : "user2583233", "age" :2583253, "sex" : 1 }
{ "_id" : ObjectId("4e27f34e256a7f5699394579"), "name" : "user2583232", "age" :2583252, "sex" : 0 }
{ "_id" : ObjectId("4e27f34e256a7f5699394578"), "name" : "user2583231", "age" :2583251, "sex" : 1 }
{ "_id" : ObjectId("4e27f34e256a7f5699394577"), "name" : "user2583230", "age" :2583250, "sex" : 0 }
{ "_id" : ObjectId("4e27f34e256a7f5699394576"), "name" : "user2583229", "age" :2583249, "sex" : 1 }
has more
> db.system.profile.find()
{ "ts" : ISODate("2011-07-21T09:36:42.515Z"),
"info" : "insert blog.users 140ms", "millis" : 140 }
{ "ts" : ISODate("2011-07-21T09:38:54.198Z"),
"info" : "query blog.users ntoreturn:10000 scanAndOrder reslen:700036 nscanned:2593249 \nquery: { query: {}, orderby: { age: -1.0 } }
nreturned:10000 11781ms", "millis" : 11781 }
-------------
ts: 操作执行时间。
info: 操作详细信息。
info.query: 查询目标(数据库.集合)。
info.ntoreturn: 客户端期望返回的文档数量。
info.nscanned: 服务器实际扫描的文档数量。
info.reslen: 查询结果字节长度。
info.nreturnned: 查询返回文档数。
millis: 操作耗时(毫秒)。
备注
如果 nscanned 远大于 nreturned,那么需要使用索引。
如果 reslen 返回字节非常大,那么考虑只获取所需的字段。
执行 update 操作时同样检查一下 nscanned,并使用索引减少文档扫描数量。
使用 db.eval() 在服务端执行某些统计操作。
减少返回文档数量,使用 skip & limit 分页。
-----------
> db.users.find().sort({age:-1}).limit(10000).explain()
{
"cursor" : "BasicCursor",
"nscanned" : 2593249,
"nscannedObjects" : 2593249,
"n" : 10000,
"scanAndOrder" : true,
"millis" : 11781,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
}
}
>

10:Master-Slaver

单Master

配置
mongod --logpath E:\mongodb\shard\master\db\log.txt --port 10001 --dbpath E:\mongodb\shard\master\db --master
mongod --logpath E:\mongodb\shard\slave\db\log.txt --port 10002 --dbpath E:\mongodb\shard\slave\db -slave --source 10.53.139.138:10001 --autoresync
//autoresync 参数会在系统发生意外情况造成主从数据不同步时,自动启动复制操作 (同步复制 10 分钟内仅执行一次)。除此之外,还可以用 --slavedelay 设定更新频率(秒)。
Master
E:\mongodb\shard\master>mongo --port 10001
MongoDB shell version: 1.8.2
connecting to: 127.0.0.1:10001/test
> db.isMaster()
{ "ismaster" : true, "maxBsonObjectSize" : 16777216, "ok" : 1 }
> db.printReplicationInfo()
configured oplog size: 47.6837158203125MB
log length start to end: 74secs (0.02hrs)
oplog first event time: Fri Jul 22 2011 14:30:32 GMT+0800
oplog last event time: Fri Jul 22 2011 14:31:46 GMT+0800
now: Fri Jul 22 2011 14:31:49 GMT+0800
> use blog
switched to db blog
> db.users.insert({name:"user", age:20, sex:1})
> db.users.find()
{ "_id" : ObjectId("4e291b52e742b344d4d84ead"), "name" : "user", "age" : 20, "sex" : 1 }
Slaver
E:\mongodb\shard\master>mongo --port 10002
MongoDB shell version: 1.8.2
connecting to: 127.0.0.1:10002/test
> db.isMaster()
{ "ismaster" : false, "maxBsonObjectSize" : 16777216, "ok" : 1 }
> db.printSlaveReplicationInfo()
source: 10.53.139.138:10001
syncedTo: Fri Jul 22 2011 14:32:16 GMT+0800
= 16secs ago (0hrs)
> use local
switched to db local
> db.sources.find()
{ "_id" : ObjectId("4e29192760dea574d7e171ae"), "host" : "10.53.139.138:10001",
"source" : "main", "syncedTo" : { "t" : 1311316386000, "i" : 1 }, "localLogTs" :
{ "t" : 0, "i" : 0 } }
> use blog
switched to db blog
> db.users.find()
{ "_id" : ObjectId("4e291b52e742b344d4d84ead"), "name" : "user", "age" : 20, "sex" : 1 }
> db.users.insert({name:"user1", age:21, sex:0})
not master

多Master

配置
mongod --logpath E:\mongodb\shard\master\db\log.txt --port 10001 --dbpath E:\mongodb\shard\master\db --master
mongod --logpath E:\mongodb\shard\master1\db\log.txt --port 10002 --dbpath E:\mongodb\shard\master1\db --master
mongod --logpath E:\mongodb\shard\slave\db\log.txt --port 10003 --dbpath E:\mongodb\shard\slave\db -slave
连接slaver添加主服务器
E:\mongodb\shard\slave>mongo --port 10003
MongoDB shell version: 1.8.2
connecting to: 127.0.0.1:10003/test
> use local
switched to db local
> db.sources.insert({host:"10.53.139.138:10001"})
> db.sources.insert({host:"10.53.139.138:10002"})
> db.printSlaveReplicationInfo()
source: 10.53.139.138:10001
doing initial sync
source: 10.53.139.138:10002
doing initial sync
master1添加数据
E:\mongodb\shard\slave>mongo --port 10001
MongoDB shell version: 1.8.2
connecting to: 127.0.0.1:10001/test
> use db1
switched to db db1
> db.users.insert({name:"user1"})
> db.users.find()
{ "_id" : ObjectId("4e291eaa8abc2b0f77aade99"), "name" : "user1" }
master2添加
E:\mongodb\shard\slave>mongo --port 10002
MongoDB shell version: 1.8.2
connecting to: 127.0.0.1:10002/test
> use db2
switched to db db2
> db.users.insert({name:"user2"})
> db.users.find()
{ "_id" : ObjectId("4e291ee418179745d0094f33"), "name" : "user2" }
连接slaver
E:\mongodb\shard\slave>mongo --port 10003
MongoDB shell version: 1.8.2
connecting to: 127.0.0.1:10003/test
> use db1
switched to db db1
> db.users.find()
{ "_id" : ObjectId("4e291eaa8abc2b0f77aade99"), "name" : "user1" }
> use db2
switched to db db2
> db.users.find()
{ "_id" : ObjectId("4e291ee418179745d0094f33"), "name" : "user2" }

11:Shard

shard0:mongod --shardsvr --port 27020 --dbpath E:\mongodb\shard\shard1\db\
shard1:mongod --shardsvr --dbpath E:\mongodb\shard\shard2\db\ --port 27021
config:mongod --configsvr --dbpath E:\mongodb\shard\Config\db\ --port 27022
连接config下
mongos --configdb 10.53.139.138:27022
mongo --port 27017
use admin
db.runCommand({addshard:"10.53.139.138:27020",name:"shard0"})
db.runCommand({addshard:"10.53.139.138:27021",name:"shard1"})
db.runCommand({listshards:1})
db.runCommand({enablesharding:"test"})
db.runCommand({shardcollection:"test.people",key:{id:1}})
use test
show collections
db.people.stats()
for (var i = 1; i <= 200003; i++) db.people.save({id:i,value1:"1234567890",value2:"1234567890",value3:"1234567890",value4:"1234567890"})

12:故障转移(Replication)

配置set1
mongod --shardsvr --logpath E:\mongodb\shard\shard1\1\log.txt --dbpath E:\mongodb\shard\shard1\1\db --port 10001 --nohttpinterface --replSet set1
mongod --shardsvr --logpath E:\mongodb\shard\shard1\2\log.txt --dbpath E:\mongodb\shard\shard1\2\db --port 10002 --nohttpinterface --replSet set1
mongod --shardsvr --logpath E:\mongodb\shard\shard1\3\log.txt --dbpath E:\mongodb\shard\shard1\3\db --port 10003 --nohttpinterface --replSet set1
E:\mongodb\shard\shard1\1>mongo --port 10001
MongoDB shell version: 1.8.2
connecting to: 127.0.0.1:10001/test
>cfg = { _id: "set1", members: [
... { _id:0, host:"10.53.139.138:10001" },
... { _id:1, host:"10.53.139.138:10002" },
... { _id:2, host:"10.53.139.138:10003" }
... ]}
> rs.initiate(cfg)
{
"info" : "Config now saved locally. Should come online in about a minute.",
"ok" : 1
}
> rs.conf()
{
"_id" : "set1",
"version" : 1,
"members" : [
{
"_id" : 0,
"host" : "localhost:27017"
},
{
"_id" : 1,
"host" : "localhost:27018"
},
{
"_id" : 2,
"host" : "localhost:27019"
}
]
}
> rs.status()
{
"set" : "set1",
"date" : "Sat Aug 21 2010 15:21:13 GMT+0800 (CST)",
"myState" : 2,
"members" : [
{
"_id" : 0,
"name" : "10.53.139.138:10001",
"health" : 1,
"state" : 2,
"stateStr" : "PRIMARY",
"uptime" : 363,
"optime" : {
"t" : 1311313830000,
"i" : 1
},
"optimeDate" : ISODate("2011-07-22T05:50:30Z"),
"lastHeartbeat" : ISODate("2011-07-22T06:00:56Z")
},
{
"_id" : 1,
"name" : "10.53.139.138:10002",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"optime" : {
"t" : 1311313830000,
"i" : 1
},
"optimeDate" : ISODate("2011-07-22T05:50:30Z"),
"self" : true
},
{
"_id" : 2,
"name" : "10.53.139.138:10003",
"health" : 1,
"state" : 1,
"stateStr" : "SECONDARY",
"uptime" : 802,
"optime" : {
"t" : 1311313830000,
"i" : 1
},
"optimeDate" : ISODate("2011-07-22T05:50:30Z"),
"lastHeartbeat" : ISODate("2011-07-22T06:00:57Z")
}
],
"ok" : 1
}
//暂停10001
set1:SECONDARY> rs.status()
{
"set" : "set1",
"date" : ISODate("2011-07-22T06:01:11Z"),
"myState" : 2,
"members" : [
{
"_id" : 0,
"name" : "10.53.139.138:10001",
"health" : 0,
"state" : 1,
"uptime" : 0,
"lastHeartbeat" : "Sat Aug 21 2010 15:40:14 GMT+0800 (CST)",
"errmsg" : "connect/transport error"
},
{
"_id" : 1,
"name" : "10.53.139.138:10002",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"optime" : {
"t" : 1311313830000,
"i" : 1
},
"optimeDate" : ISODate("2011-07-22T05:50:30Z"),
"self" : true
},
{
"_id" : 2,
"name" : "10.53.139.138:10003",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 816,
"optime" : {
"t" : 1311313830000,
"i" : 1
},
"optimeDate" : ISODate("2011-07-22T05:50:30Z"),
"lastHeartbeat" : ISODate("2011-07-22T06:01:11Z")
}
],
"ok" : 1
}
//开启10001
set1:SECONDARY> rs.status()
{
"set" : "set1",
"date" : ISODate("2011-07-22T06:01:43Z"),
"myState" : 2,
"members" : [
{
"_id" : 0,
"name" : "10.53.139.138:10001",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 409,
"optime" : {
"t" : 1311313830000,
"i" : 1
},
"optimeDate" : ISODate("2011-07-22T05:50:30Z"),
"lastHeartbeat" : ISODate("2011-07-22T06:01:42Z")
},
{
"_id" : 1,
"name" : "10.53.139.138:10002",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"optime" : {
"t" : 1311313830000,
"i" : 1
},
"optimeDate" : ISODate("2011-07-22T05:50:30Z"),
"self" : true
},
{
"_id" : 2,
"name" : "10.53.139.138:10003",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 848,
"optime" : {
"t" : 1311313830000,
"i" : 1
},
"optimeDate" : ISODate("2011-07-22T05:50:30Z"),
"lastHeartbeat" : ISODate("2011-07-22T06:01:43Z")
}
],
"ok" : 1
}
set1:SECONDARY> exit
bye
//准备10004
E:\mongodb\shard\shard1\1>mongo --port 10001
MongoDB shell version: 1.8.2
connecting to: 127.0.0.1:10001/test
set1:SECONDARY> rs.status()
{
"set" : "set1",
"date" : ISODate("2011-07-22T06:02:26Z"),
"myState" : 2,
"members" : [
{
"_id" : 0,
"name" : "10.53.139.138:10001",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"optime" : {
"t" : 1311313830000,
"i" : 1
},
"optimeDate" : ISODate("2011-07-22T05:50:30Z"),
"self" : true
},
{
"_id" : 1,
"name" : "10.53.139.138:10002",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 454,
"optime" : {
"t" : 1311313830000,
"i" : 1
},
"optimeDate" : ISODate("2011-07-22T05:50:30Z"),
"lastHeartbeat" : ISODate("2011-07-22T06:02:24Z")
},
{
"_id" : 2,
"name" : "10.53.139.138:10003",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 454,
"optime" : {
"t" : 1311313830000,
"i" : 1
},
"optimeDate" : ISODate("2011-07-22T05:50:30Z"),
"lastHeartbeat" : ISODate("2011-07-22T06:02:24Z")
}
],
"ok" : 1
}
//非PRIMARY不能动态添加节点
set1:SECONDARY> rs.add("10.53.139.138:10004")
{
"errmsg" : "replSetReconfig command must be sent to the current replica
set primary.",
"ok" : 0
}
set1:SECONDARY> exit
bye
E:\mongodb\shard\shard1\1>mongo --port 10003
MongoDB shell version: 1.8.2
connecting to: 127.0.0.1:10003/test
set1:PRIMARY> rs.add("10.53.139.138:10004")
Fri Jul 22 14:03:24 DBClientCursor::init call() failed
Fri Jul 22 14:03:24 query failed : admin.$cmd { replSetReconfig: { _id: "set1",version: 2, members: [ { _id: 0, host: "10.53.139.138:10001" }, { _id: 1, host:
"10.53.139.138:10002" }, { _id: 2, host: "10.53.139.138:10003" }, { _id: 3.0, host: "10.53.139.138:10004" } ] } } to: 127.0.0.1:10003
shell got exception during reconfig: Error: error doing query: failed
in some circumstances, the primary steps down and closes connections on a reconf
ig
null
Fri Jul 22 14:03:24 trying reconnect to 127.0.0.1:10003
Fri Jul 22 14:03:24 reconnect 127.0.0.1:10003 ok
set1:PRIMARY> rs.status()
{
"set" : "set1",
"date" : ISODate("2011-07-22T06:03:50Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "10.53.139.138:10001",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 24,
"optime" : {
"t" : 1311314604000,
"i" : 1
},
"optimeDate" : ISODate("2011-07-22T06:03:24Z"),
"lastHeartbeat" : ISODate("2011-07-22T06:03:48Z")
},
{
"_id" : 1,
"name" : "10.53.139.138:10002",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 24,
"optime" : {
"t" : 1311314604000,
"i" : 1
},
"optimeDate" : ISODate("2011-07-22T06:03:24Z"),
"lastHeartbeat" : ISODate("2011-07-22T06:03:48Z")
},
{
"_id" : 2,
"name" : "10.53.139.138:10003",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"optime" : {
"t" : 1311314604000,
"i" : 1
},
"optimeDate" : ISODate("2011-07-22T06:03:24Z"),
"self" : true
},
{
"_id" : 3,
"name" : "10.53.139.138:10004",
"health" : 1,
"state" : 3,
"stateStr" : "RECOVERING", //新增加的节点 正在恢复数据 完成后为 SECONDARY
"uptime" : 20,
"optime" : {
"t" : 1311314604000,
"i" : 1
},
"optimeDate" : ISODate("2011-07-22T06:03:24Z"),
"lastHeartbeat" : ISODate("2011-07-22T06:03:48Z"),
"errmsg" : "initial sync done"
}
],
"ok" : 1
}
set1:PRIMARY> exit
bye
//连接新加入的10004
E:\mongodb\shard\shard1\1>mongo --port 10004
MongoDB shell version: 1.8.2
connecting to: 127.0.0.1:10004/test
set1:SECONDARY> db.users.find()
error: { "$err" : "not master and slaveok=false", "code" : 13435 }
set1:SECONDARY>

13:集群方案

Set1
mongod --shardsvr --logpath E:\mongodb\shard\shard1\1\log.txt --dbpath E:\mongodb\shard\shard1\1\db --port 10001 --nohttpinterface --replSet set1
mongod --shardsvr --logpath E:\mongodb\shard\shard1\2\log.txt --dbpath E:\mongodb\shard\shard1\2\db --port 10002 --nohttpinterface --replSet set1
mongod --shardsvr --logpath E:\mongodb\shard\shard1\3\log.txt --dbpath E:\mongodb\shard\shard1\3\db --port 10003 --nohttpinterface --replSet set1
配置
E:\mongodb\shard\shard1\1>mongo --port 10001
MongoDB shell version: 1.8.2
connecting to: 127.0.0.1:10001/test
> cfg = { _id:'set1', members:[
... ... { _id:0, host:'10.53.139.138:10001' },
... ... { _id:1, host:'10.53.139.138:10002' },
... ... { _id:2, host:'10.53.139.138:10003' }
... ... ]};
{
"_id" : "set1",
"members" : [
{
"_id" : 0,
"host" : "10.53.139.138:10001"
},
{
"_id" : 1,
"host" : "10.53.139.138:10002"
},
{
"_id" : 2,
"host" : "10.53.139.138:10003"
}
]
}
> rs.initiate(cfg)
{
"info" : "Config now saved locally. Should come online in about a minut
e.",
"ok" : 1
}
> rs.status()
{
"set" : "set1",
"date" : ISODate("2011-07-21T10:14:08Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "10.53.139.138:10001",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"optime" : {
"t" : 1311243232000,
"i" : 1
},
"optimeDate" : ISODate("2011-07-21T10:13:52Z"),
"self" : true
},
{
"_id" : 1,
"name" : "10.53.139.138:10002",
"health" : 0,
"state" : 6,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : {
"t" : 0,
"i" : 0
},
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2011-07-21T10:14:07Z"),
"errmsg" : "still initializing"
},
{
"_id" : 2,
"name" : "10.53.139.138:10003",
"health" : 1,
"state" : 3,
"stateStr" : "RECOVERING",
"uptime" : 5,
"optime" : {
"t" : 0,
"i" : 0
},
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2011-07-21T10:14:07Z"),
"errmsg" : "initial sync need a member to be primary or
secondary to do our initial sync"
}
],
"ok" : 1
}
set1:PRIMARY> exit
bye
set2
mongod --shardsvr --logpath E:\mongodb\shard\shard2\1\log.txt --dbpath E:\mongodb\shard\shard2\1\db --port 10011 --nohttpinterface --replSet set2
mongod --shardsvr --logpath E:\mongodb\shard\shard2\2\log.txt --dbpath E:\mongodb\shard\shard2\2\db --port 10012 --nohttpinterface --replSet set2
mongod --shardsvr --logpath E:\mongodb\shard\shard2\3\log.txt --dbpath E:\mongodb\shard\shard2\3\db --port 10013 --nohttpinterface --replSet set2
配置set2
E:\mongodb\shard\shard2\1>mongo --port 10011
MongoDB shell version: 1.8.2
connecting to: 127.0.0.1:10011/test
> cfg = { _id:'set1', members:[
... ... { _id:0, host:'10.53.139.138:10011' },
... ... { _id:1, host:'10.53.139.138:10012' },
... ... { _id:2, host:'10.53.139.138:10013' }
... ... ]};
{
"_id" : "set1",
"members" : [
{
"_id" : 0,
"host" : "10.53.139.138:10011"
},
{
"_id" : 1,
"host" : "10.53.139.138:10012"
},
{
"_id" : 2,
"host" : "10.53.139.138:10013"
}
]
}
> cfg = { _id:'set2', members:[
... ... { _id:0, host:'10.53.139.138:10011' },
... ... { _id:1, host:'10.53.139.138:10012' },
... ... { _id:2, host:'10.53.139.138:10013' }
... ... ]};
{
"_id" : "set2",
"members" : [
{
"_id" : 0,
"host" : "10.53.139.138:10011"
},
{
"_id" : 1,
"host" : "10.53.139.138:10012"
},
{
"_id" : 2,
"host" : "10.53.139.138:10013"
}
]
}
> rs.initiate(cfg)
{
"info" : "Config now saved locally. Should come online in about a minut
e.",
"ok" : 1
}
> rs.status()
{
"set" : "set2",
"date" : ISODate("2011-07-21T10:19:33Z"),
"myState" : 2,
"members" : [
{
"_id" : 0,
"name" : "10.53.139.138:10011",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"optime" : {
"t" : 1311243565000,
"i" : 1
},
"optimeDate" : ISODate("2011-07-21T10:19:25Z"),
"self" : true
},
{
"_id" : 1,
"name" : "10.53.139.138:10012",
"health" : 0,
"state" : 6,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : {
"t" : 0,
"i" : 0
},
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2011-07-21T10:19:32Z"),
"errmsg" : "still initializing"
},
{
"_id" : 2,
"name" : "10.53.139.138:10013",
"health" : 0,
"state" : 6,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : {
"t" : 0,
"i" : 0
},
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2011-07-21T10:19:32Z"),
"errmsg" : "still initializing"
}
],
"ok" : 1
}
set2:SECONDARY> exit
bye
配置configserver
mongod --configsvr --logpath E:\mongodb\shard\Config\1\log.txt --dbpath E:\mongodb\shard\Config\1\db --port 20000 --nohttpinterface
mongod --configsvr --logpath E:\mongodb\shard\Config\2\log.txt --dbpath E:\mongodb\shard\Config\2\db --port 20001 --nohttpinterface
mongod --configsvr --logpath E:\mongodb\shard\Config\3\log.txt --dbpath E:\mongodb\shard\Config\3\db --port 20002 --nohttpinterface
启动routserver
mongos --logpath E:\mongodb\shard\rout\log.txt --configdb 10.53.139.138:20000,10.53.139.138:20001,10.53.139.138:20002
配置分片
E:\mongodb\shard\shard2\1>cd E:\mongodb\shard\rout
E:\mongodb\shard\rout>mongo
MongoDB shell version: 1.8.2
connecting to: test
> use admin
switched to db admin
> db.runCommand({ addshard:'set1/10.53.139.138:10001,10.53.139.138:10002,10.53.1
39.138:10003' })
{ "shardAdded" : "set1", "ok" : 1 }
> db.runCommand({ addshard:'set2/10.53.139.138:10011,10.53.139.138:10012,10.53.1
39.138:10013' })
{ "shardAdded" : "set2", "ok" : 1 }
> db.runCommand({ shardcollection:'test.data', key:{_id:1} })
{ "ok" : 0, "errmsg" : "sharding not enabled for db" }
> db.runCommand({ shardcollection:'test.data', key:{_id:1} })
{ "ok" : 0, "errmsg" : "sharding not enabled for db" }
> db.runCommand({ listshards:1 })
{
"shards" : [
{
"_id" : "set1",
"host" : "set1/10.53.139.138:10001,10.53.139.138:10002,1
0.53.139.138:10003"
},
{
"_id" : "set2",
"host" : "set2/10.53.139.138:10011,10.53.139.138:10012,1
0.53.139.138:10013"
}
],
"ok" : 1
}
> printShardingStatus()
--- Sharding Status ---
sharding version: { "_id" : 1, "version" : 3 }
shards:
{
"_id" : "set1",
"host" : "set1/10.53.139.138:10001,10.53.139.138:10002,10.53.139.138:100
03"
}
{
"_id" : "set2",
"host" : "set2/10.53.139.138:10011,10.53.139.138:10012,10.53.139.138:100
13"
}
databases:
{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
{ "_id" : "test", "partitioned" : false, "primary" : "set1" }
简单测试
> use test
switched to db test
> db.data.insert({name:1})
> db.data.insert({name:2})
> db.data.insert({name:3})
> db.data.find()
{ "_id" : ObjectId("4e28015cbb9f26c67deacec6"), "name" : 1 }
{ "_id" : ObjectId("4e28015ebb9f26c67deacec7"), "name" : 2 }
{ "_id" : ObjectId("4e280160bb9f26c67deacec8"), "name" : 3 }

www.htsjk.Com true http://www.htsjk.com/MongoDB/10344.html NewsArticle 操作MongoDB, 有用的命令 db.helpdb.collectionname.help 时区问题 db.test.insert({ " date " : new Date( " 2012-2-2 " ), " num " : 1 }) db.test.insert({ " date " : new Date( " 2012-02-02 " ), " num " : 2 }) db.test.insert({ " date...
相关文章
    暂无相关文章
评论暂时关闭