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查询游标的理解。
第三,mongo shell, 有个好东西, 当敲一个命令的时候,不敲后边跟上的括号,就能显示该命令底下将会执行的js方法。
比如以下命令:
> db.m.find 回车后会显示对应的方法。
另外,有个挺好用的mongodb客户端:robomongo 值得推荐。
时间: 2024-11-09 00:21:32