设为首页 收藏本站
查看: 1720|回复: 0

[经验分享] mongodb 修改数据结构的一个例子以及小梳理

[复制链接]

尚未签到

发表于 2015-7-8 11:35:11 | 显示全部楼层 |阅读模式
  mongodb的存储结构是灵活可变的,但是,并不意味着我们就肆意地使用不规则的文档结构。不规则的文档结构对于开发和后期的维护都是一个灾难。所以,还是要有一个约定的格式。
  但是,由于前期设计的不周详和其他种种原因,数据库文档结构在开发过程的中修改总是难以避免的,应该尽量减少这种修改。但是,到了必须改的时候还是得改:



1 {
2 "_id" : ObjectId("54a1f775e4b03dad3af55c3c"),
3 "myId" : "54a0b115e4b00712935204ba",
4 "name" : "action",
5 "key" : "m_0",
6 "index" : 0,
7 "createTime" : ISODate("2014-12-30T00:53:09.483Z"),
8 "subMs" : [
9 {
10 "_id" : null,
11 "rm" : {
12 "mt" : "TEXT",
13 "content" : "撒东西"
14 },
15 "name" : "地说道",
16 "key" : "menu_0_0",
17 "type" : "CLICK"
18 }
19 ]
20 }
21 {
22 "_id" : ObjectId("54b87996e4b04b29b92a71b1"),
23 "myId" : "54b5e8cce4b045d4121f5d63",
24 "rm" : {
25 "msgType" : "URL",
26 "url" : "http://www.abc.com"
27 },
28 "name" : "usercenter",
29 "key" : "user-center",
30 "type" : "VIEW",
31 "index" : 0,
32 "createTime" : ISODate("2015-01-16T02:38:14.643Z")
33 }]
34
35 }
  有很多这样类型的文档。 这个文档中的subMs字段中内嵌有若干个文档。要做的事情就是把subMs中的若干个文档脱离出来成为一个独立的文档,并且使新拆出来的文档保留原父文档的id。
  脚本如下:



1 var mList = db.m.find();
2 var mLength = mList.length;
3 var mArray = new Array();
4 // 这一步比较关键,因为find 方法会返回一个游标,
5 // 如果不先关闭,或者将此游标用完,接下来在继续往
6 // mongodb中插入数据会导致该游标发生混乱。
7 // 所以此处未往mongodb中修改前先把游标用完。
8 while(mList.hasNext()) {  
9     mArray.push(mList.next());
10 }
11 for(var i = 0; i < mLength; i ++) {
12     var mItem = mArray.pop();
13     var sMList = mItem.subMs;
14     mItem.subMs = new Array();
15     if(sMList == 0 || sMList.slength == 0) {
16         continue;
17     }
18     var sMLength = sMList.slength;
19     for(var j = 0; j < sMLength; j ++) {
20         var sMItem = sMList.pop();
21         sMItem.pid = mItem._id.str;
22         sMItem.index = j;
23         sMItem.subMs = new Array();
24         sMItem._id = undefined;
25         db.m.insert(sMItem);
26     }
27     db.m.save(mItem);
28 }
  
  第一次写起来还是有点吃力,
  第一,是由于js的非常不熟悉。翻了好几次w3school才看出了点东西。
  第二,是对mongodb查询游标的理解。
  着重说说,mongodb 的游标:
  游标:在mongodb查询中,返回一个可迭代的对象,这个对象就叫做游标。这个对象保存着所有的查询结果集。
  游标的行为:
  1. 在mongo shell 中,游标默认显示前20个结果集,敲入 it 翻页。显示下一个 20个。
  关闭mongodb 的游标:游标在mongodb中如果没有被迭代到最后,那么它在10分钟后自动关闭。或者是被迭代到最后。
  修改mongodb游标的自动过期时间方法为:
  var myCursor = db.m.find().addOption(DBQuery.Option.noTimeout);
  // DBQuery 这个对象中也有挺多东西,有空翻来看看
  由于游标在生存周期中不是隔离的,游标存活期间在对一个文档的写操作可能会时该文档的返回次数超过一次。当这个文档被改变之后,这就是我在写上面脚本的时候一开始缺少了先把游标用完,就对原文档修改,造成错误。
  所以,我上面的写法存在问题,当数据量很大的时候,把游标中所有的东西加载到内存后会把内存撑爆的。。。
  解决办法:使用游标快照: (P707)
  mongodb的游标会对一个文档返回超过一次,在一些特殊的情况下,那么这个时候就可以使用快照方法 snapshot().
  snapshot()贯穿在_id字段上的索引,保证查询返回的每个文档出现的_id值不超过一次。(遵循_id值)
  快照方法不保证数据返回时会返回单一时刻。 也不保证对插入和删除操作的隔离。
  
  警告:
  1.不能再分片集合中使用快照方法
  2.不能在快照方法的同时使用 sort方法或者hint()方法。
  
  作为一个选择,如果在集合中存在有一个或多个字段是永远不会改变的,那么可以在该字段上创建唯一索引,来得到和使用库依照方法类似的集合。查询时使用hint方法强制查询时使用这个唯一索引。
  
  
  第三,mongo shell, 有个好东西, 当敲一个命令的时候,不敲后边跟上的括号,就能显示该命令底下将会执行的js方法。
  比如以下命令:   
  >  db.m.find   回车后会显示对应的方法。
  另外,有个挺好用的mongodb客户端:robomongo 值得推荐。
  
  
  以上参考了mongodb的官方文档。写的很给力的一个文档。非常值得一看,居家备用查询也挺好。
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-84455-1-1.html 上篇帖子: 使用Node.js + Mongodb构建基于Cloud Foundry的项目 下篇帖子: mongodb一个关键字对多个字段同时查询,mongodb $or $and查询
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表