MongoDB的使用之前也分享过一篇,稍微高阶点:见这里:《MongoDB使用小结》
1、shell登陆和显示
假设在本机上有一个端口为17380的MongoDB服务,假设已经把mongo bin文件加入到系统PATH下。
登陆:mongo –port 17380
显示DB:show dbs
进入某DB:use test_cswuyg
显示集合:show tables
2、简单查找
查找文档:db.test_mac_id.find({‘a’: ‘b’})
删除文档:db.test_mac_id.remove({‘a’: ‘b’})
查找找到某一天的数据:
db.a.find({‘D’ : ISODate(‘2014-04-21T00:00:00Z’)}) 或者 db.a.find({‘D’ : ISODate(‘2014-04-21’)})
删除某一天的数据:
db.region_mac_id_result.remove({“D” : ISODate(‘2014-04-17’)})
小于2014.6.5的数据:
db.xxx.find({E: {$lt :ISODate(‘2014-06-05’)}})
大于等于2014.6.1的数据:
db.xxx.find({E: {$gte: ISODate(“2014-05-29”)}}).count()
两个条件:
db.xxx.find({E:{$gte: ISODate(“2014-05-29”), $lte: ISODate(“2014-06-04”)}}).count()
json中的嵌套对象查询,采用“点”的方式:
mongos> db.wyg.find({“a.b”: {$exists: true}})
{ “_id” : “c”, “a” : { “b” : 10 } }
某个字段存在,且小于1000有多少:
db.stat.find({_: ISODate(“2014-06-17”), “123”: {$exists: 1, $lte: 1000}}, {“123”: 1}).count()
3、存在和遍历统计
存在’i’: 1,且存在old_id字段:
mongos> var it = db.test.find({‘i’: 1, “old_id”: {$exists: 1}})
遍历计数1:mongos> var count = 0;while(it.hasNext()){if (it.next()[“X”].length==32)++count}print(count)
遍历计数2:mongos> var count = 0;while(it.hasNext()){var item = it.next(); if (item[‘X’].length==32 && item[‘_id’] != item[‘X’])++count;if(!item[‘X’])++count;}print(count)
4、插入和更新
> db.test.findOne({_id: ‘cswuyg’})
null
> db.test.insert({‘_id’: ‘cswuyg’, ‘super_admin’: true})
> db.test.findOne({‘_id’: ‘cswuyg’})
{
“_id” : “cswuyg”,
“super_admin” : true
}
db.test.update({‘_id’: ‘cswuyg’}, {$set: {‘super_admin’: true}})
5、repair 操作
对某个DB执行repair:进入要repair的db,执行db.repairDatabase()
对mongodb整个实例执行repair:numactl –interleave=all /mongod –repair –dbpath=/home/disk1/mongodata/shard/
6、mongodb任务操作
停止某个操作:
http://stackoverflow.com/questions/5191186/how-do-i-dump-data-for-a-given-date
(2)从运行的MongoD中导出指定日期数据,采用-q查询参数:
mongodump -h xxxhost –port 17380 –db cswuyg –collection test -q “{D: {\$gte: {\$date: `date -d “20140410” +%s`000}, \$lt: {\$date: `date +%s`000}}}”
mongodump -dbpath=/home/disk3/mongodb/data/shard1/ -d cswuyg -c test -o /home/disk9/mongodata/shard1_2/ -q “{_:{\$gte:{\$date:`date -d “20140916” +%s`000}, \$lt: {\$date: `date -d “20140918” +%s`000}}}”
dump出来的bson文件去掉了索引、碎片空间,所有相比DB磁盘文件要小很多。
26、restore DB
restore的时候,不能先建索引,必须是restore完数据之后再建索引,否则restore的时候会非常慢。而且一般不需要自己手动建索引,在数据bson文件的同目录下有一个索引bson文件(system.indexes.bson),restore完数据之后会mongorestore自动根据该文件创建索引。
(1)从某个文件restore
mongorestore –host xxxhost –port 17380 –db cswuyg –collection cswuyg ./cswuyg_1406330331/cswuyg/cswuyg_bak.bson
(2)从目录restore
./mongorestore –port 27018 /home/disk2/mongodata/shard/
(3)dump 和 restore configure server:
mongodump –host xxxhost –port 19913 –db config -o /home/work/cswuyg/test/config
mongorestore –host xxxhost –port 19914 /home/work/cswuyg/test/config
27、创建索引
看看当前的test collection上有啥索引:
http://docs.mongodb.org/manual/reference/command/count/“On a sharded cluster, count can result in an inaccurate count if orphaned documents exist or if a chunk migration is in progress.
To avoid these situations, on a sharded cluster, use the $group stage of the db.collection.aggregate()method to $sum the documents. ”
31、自定义MongoDB操作函数
可以把自己写的js代码保存在某个地方,让MongoDB加载它,然后就可以在MongoDB的命令行里操作它们。
mongodb shell默认会加载~/.mongorc.js文件
例如以下修改了启动提示文字、左侧提示文字,增加了my_show_shards shell函数用于显示当前sharded collection的chunks在各分片的负载情况:
http://blog.zawodny.com/2011/03/06/mongodb-pre-splitting-for-faster-data-loading-and-importing/35、DB重命名
db.copyDatabase(“xx_config_20141113”, “xx_config”)
use xx_config_20141113
db.dropDatabase();
远程拷贝DB :
db.copyDatabase(fromdb, todb, fromhost, username, password)
db.copyDatabase(“t_config”, “t_config_v1”, “xxxhost: 17380”)
这个拷贝过程很慢。
注意,sharded的DB是无法拷贝的,所以sharded的DB也无法采用上面的方式重命名。
参考: http://docs.objectrocket.com/features.html “Your remote database is sharded through mongos.”
http://docs.mongodb.org/manual/tutorial/aggregation-with-user-preference-data/http://docs.mongodb.org/manual/reference/operator/aggregation/
http://api.mongodb.org/python/current/api/pymongo/collection.html
2.6之前的MongoDB,管道不支持超过16MB的返回集合。
可以使用$out操作符,把结果写入到collection中。如果aggregation成功,$out会替换已有的colleciton,但不会修改索引信息,如果失败,则什么都不做。
http://docs.mongodb.org/manual/reference/operator/aggregation/out/
http://stackoverflow.com/questions/26640861/movechunk-failed-to-engage-to-shard-in-the-data-transfer-cant-accept-new-chunk45、MongoDB升级后的兼容问题
MongoDB 2.4切换到2.6之后,出现数据没有插入,pymongo代码:
update_obj = {“$set” : {“a”: 1}}
update_obj[“$inc”] = inc_objs
update_obj[“$push”] = list_objs
db.test.update({“_id”: id}, update_obj, True)
2.6里,inc如果是空的,则会导致整条日志没有插入,2.4则inc为空也可以正常运行。
http://www.lanceyan.com/category/tech/mongodbhttp://api.mongodb.org/python/current/api/pymongo/read_preferences.html
http://api.mongodb.org/python/current/api/pymongo/mongo_client.html
注意:3.0之后MongoReplicaSetClient函数是要被放弃的。
但是测试时发现:在较低版本中,需要使用MongoReplicaSetClient,MongoClient无法实现 pymongo.ReadPreference.SECONDARY_PREFERRED功能。
2015.12.28补充:
51、为副本集设置标签
可以为副本集中的每个成员设置tag(标签),设置标签的好处是后面读数据时,应用可以指定从某类标签的副本上读数据。
52、副本集碎片整理的一种方法
使用MMAPv1存储引擎时,对于频繁大数据量的写入删除操作,碎片问题会变得很严重。在数据同步耗时不严重的情况下,我们不需要对每个副本做repair,而是轮流“卸下副本,删除对应的磁盘文件,重新挂上副本”。每个重新挂上的副本都会自动去重新同步一遍数据,碎片问题就解决了。
53、存储引擎升级为wiredTiger
我们当前的版本是MongoDB3.0.6,没有开启wiredTiger引擎,现在打算升级到wiredTiger引擎。
我们是Shared Cluster,shard是Replica Set。升级比较简单,只需要逐步对每一个副本都执行存储引擎升级即可,不影响线上服务。
升级时,只在启动命令中添加:–storageEngine wiredTiger。
步骤:首先,下掉一个副本;然后,把副本的磁盘文件删除掉;接着,在该副本的启动命令中添加–storageEngine wiredTiger后启动。这就升级完一个副本,等副本数据同步完成之后,其它副本也照样操作(或者处理完一个副本之后,拷贝该副本磁盘文件替换掉另一个副本的磁盘文件)。风险:如果数据量巨大,且有建索引的需求,容易出现内存用尽。
分片集群的configure server可以不升级。
升级之后磁盘存储优化效果极度明显,22GB的数据会被精简到1.3GB。
升级后的磁盘文件完全变了,所以不同存储引擎下的磁盘文件不能混用。
升级参考:https://docs.mongodb.org/manual/tutorial/change-sharded-cluster-wiredtiger/
54、oplogSizeMB不要设置得太大
启动配置中的这个字段是为了设置oplog collection的大小,oplog是操作记录,它是一个capped collection,在副本集群中,设置得太小可能导致secondary无法及时从primary同步数据。默认情况下是磁盘大小的5%。但是,如果这个字段设置得太大,可能导致暴内存,oplog的数据几乎是完全加载在内存中,一旦太大,必然暴内存,导致OOM。而且因为这个collection是capped,MongoDB启动之后无法修改其大小。