mongodb 修改数据结构的一个例子以及小梳理

时间:2022-06-14 06:58:49

mongodb的存储结构是灵活可变的,但是,并不意味着我们就肆意地使用不规则的文档结构。不规则的文档结构对于开发和后期的维护都是一个灾难。所以,还是要有一个约定的格式。

但是,由于前期设计的不周详和其他种种原因,数据库文档结构在开发过程的中修改总是难以避免的,应该尽量减少这种修改。但是,到了必须改的时候还是得改:

 {
"_id" : ObjectId("54a1f775e4b03dad3af55c3c"),
"myId" : "54a0b115e4b00712935204ba",
"name" : "action",
"key" : "m_0",
"index" : 0,
"createTime" : ISODate("2014-12-30T00:53:09.483Z"),
"subMs" : [
{
"_id" : null,
"rm" : {
"mt" : "TEXT",
"content" : "撒东西"
},
"name" : "地说道",
"key" : "menu_0_0",
"type" : "CLICK"
}
]
}
{
"_id" : ObjectId("54b87996e4b04b29b92a71b1"),
"myId" : "54b5e8cce4b045d4121f5d63",
"rm" : {
"msgType" : "URL",
"url" : "http://www.abc.com"
},
"name" : "usercenter",
"key" : "user-center",
"type" : "VIEW",
"index" : 0,
"createTime" : ISODate("2015-01-16T02:38:14.643Z")
}] }

有很多这样类型的文档。 这个文档中的subMs字段中内嵌有若干个文档。要做的事情就是把subMs中的若干个文档脱离出来成为一个独立的文档,并且使新拆出来的文档保留原父文档的id。

脚本如下:

 var mList = db.m.find();
var mLength = mList.length;
var mArray = new Array();
// 这一步比较关键,因为find 方法会返回一个游标,
// 如果不先关闭,或者将此游标用完,接下来在继续往
// mongodb中插入数据会导致该游标发生混乱。
// 所以此处未往mongodb中修改前先把游标用完。
while(mList.hasNext()) {
mArray.push(mList.next());
}
for(var i = 0; i < mLength; i ++) {
var mItem = mArray.pop();
var sMList = mItem.subMs;
mItem.subMs = new Array();
if(sMList == 0 || sMList.slength == 0) {
continue;
}
var sMLength = sMList.slength;
for(var j = 0; j < sMLength; j ++) {
var sMItem = sMList.pop();
sMItem.pid = mItem._id.str;
sMItem.index = j;
sMItem.subMs = new Array();
sMItem._id = undefined;
db.m.insert(sMItem);
}
db.m.save(mItem);
}

第一次写起来还是有点吃力,

第一,是由于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的官方文档。写的很给力的一个文档。非常值得一看,居家备用查询也挺好。

mongodb 修改数据结构的一个例子以及小梳理的更多相关文章

  1. Spark小课堂Week7 从Spark中一个例子看面向对象设计

    Spark小课堂Week7 从Spark中一个例子看面向对象设计 今天我们讨论了个问题,来设计一个Spark中的常用功能. 功能描述:数据源是一切处理的源头,这次要实现下加载数据源的方法load() ...

  2. 一个有趣的小例子&comma;带你入门协程模块-asyncio

    一个有趣的小例子,带你入门协程模块-asyncio 上篇文章写了关于yield from的用法,简单的了解异步模式,[https://www.cnblogs.com/c-x-a/p/10106031. ...

  3. &lbrack;python&rsqb;python 遍历一个list 的小例子:

    [python]python 遍历一个list 的小例子: mlist=["aaa","bbb","ccc"]for ss in enume ...

  4. C&num; 关于委托和事件的妙文:通过一个例子详细介绍委托和事件的作用;Observer模式简介

    委托和事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见 ...

  5. Erlang 程序引发共享内存 bug 的一个例子

    虽然 Erlang 的广告说得非常好,functional.share-nothing.消息传递,blah blah 的,好像用 Erlang 写并发程序就高枕无忧了,但是由于 Erlang 信奉高度 ...

  6. 【C语言探索之旅】 第一部分第八课:第一个C语言小游戏

    ​ 内容简介 1.课程大纲 2.第一部分第八课:第一个C语言小游戏 3.第一部分第九课预告: 函数 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编写 ...

  7. 6、GNU makefile工程管理学习的一个例子

    在之前我们已经学习了一个文件的编译过程,但是做过项目的都知道,一个工程中的源文件不计其数,其按类型.功能.模块会分别放在若干个目录中,而这些文件如何编译就需要有一个编译规则,虽然现在很多大型的项目都是 ...

  8. 一个例子理解Predicate、Consumer和Stream

    一个需求: 把年龄大于20的学生的信息打印出来. 面向对象编程 public class Student { private String name; private int age; private ...

  9. 一个例子看懂所有nodejs的官方网络demo

    今天看群里有人用AI技术写了个五子棋,正好用的socket.io,本身我自己很久没看nodejs了,再加上Tcp/IP的知识一直很弱,我就去官网看了下net.socket 发现之前以为懂的一个官方例子 ...

随机推荐

  1. &lbrack;ASP&period;NET Core&rsqb; Getting Started

    前言 本篇文章介绍如何快速建立一个ASP.NET Core应用程序,为自己留个纪录也希望能帮助到有需要的开发人员. ASP.NET Core官网 环境 建立一个ASP.NET Core应用程序,首先要 ...

  2. Spring—Quartz定时调度CronTrigger时间配置格式的实例

    格式说明:[秒] [分] [小时] [日] [月] [周] [年] 序号 说明 是否必填 允许填写的值 允许的通配符 1 秒 是 0-59 , - * / 2 分 是 0-59 , - * / 3 小 ...

  3. python---psutil

    系统性能信息模块psutil psutil是一个跨平台库,能够轻松实现获取系统运行的进程和系统利用率(CPU,内存,磁盘,网络等)信息,主要应用于系统监控,分析和限制系统资源及进程的管理,它实现了同等 ...

  4. bzoj1066

    首先,我们可以想到从源点向每个有蜥蜴的地方连边,然后拆点,因为我们不能把一个点连向多条边,这样修改边的时候不可以,所以拆个点,就可以了 #include<iostream> #includ ...

  5. 从0开始学Java——从jsp到servlet转换的各种辅助元素介绍

    1. 指示元素,<%@指示元素 [属性=值]* %> 其中指示元素包括page, include, 和tablib三个. 其中  属性=值 可以有多对. 其中page用来告知容器如何转译目 ...

  6. BZOJ1579 &lbrack;Usaco2009 Feb&rsqb;Revamping Trails 道路升级

    各种神作不解释QAQQQ 先是写了个作死的spfa本机过了交上去T了... 然后不想写Dijkstra各种自暴自弃... 最后改了一下步骤加了个SLF过了... 首先一个trivial的想法是$dis ...

  7. Win7&plus;VS2013初试Thrift

    win7环境下VS2013编译boost_1_58_0步骤: 官网下载boost_1_58_0(直接下载),解压 cmd窗口cd到boost_1_58_0,执行bootstrap.bat cmd窗口获 ...

  8. ASP&period;NET Redis 开发&lpar;转载&rpar;

    Redis简介 Redis是一个开源的,使用C语言编写,面向“键/值”对类型数据的分布式NoSQL数据库系统,特点是高性能,持久存储,适应高并发的应用场景.Redis纯粹为应用而产生,它是一个高性能的 ...

  9. WARN &lbrack;main&rsqb; conf&period;HiveConf &lpar;HiveConf&period;java&colon;initialize&lpar;1488&rpar;&rpar; - DEPRECATED

    问题描述:hive 关于告警问题的解决:WARN  [main] conf.HiveConf (HiveConf.java:initialize(1488)) - DEPRECATED: Config ...

  10. mysql 查询条件中文问题

    这是mysql字符编码的问题,因为mysql默认的字符编码为latin1它并不识别中文,所以在读取查询语句时会出现乱码 从而使查询条件不正确所以我们只需要更改它的字符编码就可以一般都是用utf8 这里 ...