mongodb进阶
一、游标
先插入一张表的数据
for(i=0; i<100; i++) { db.c.insert({x : i}); }
定义一个游标
var cursor = db.c.find();
以循环的方式输出游标的数据
while (cursor.hasNext()) { obj = cursor.next(); print(obj.x); }
二 、limit、 skip、sort
db.c.find().limit(3) 取出前三行
db.c.find().skip(3) 滤到前三行,
db.c.find().skip(10).limit(5)从11行开始,读出5行。
定义一个游标 并按x列排序,1 表示升序,-1表示降序
var cursor= db.c.find().skip(10).limit(6).sort({"x":1)});
(一)、用skip实现分页
n 当skip大量行的时候,会比较慢
//do not use , slow for large skips
var page1 = db.foo.find(criteria).limit(100)
var page1 = db.foo.find(criteria).skip(100).limit(100)
var page1 = db.foo.find(criteria).skip(200).limit(100)
(二)、技巧
var page1 = db.foo.find().sort({"date":-1}.limit(100)
var latest = null
//display first page
whill (page1.hasNext(*)){
last=page1.next();
display(latest);
}
//get the next page
var page2 = db.foo.find ({"data":("$gt":latest.data}});
page2.sort({"date":-1}.limit(100)
这样做就不会存在大量的分页。
(三)、随机抽取文档
db.people.insert({"name" : "joe", "random" : Math.random()})
db.people.insert({"name" : "john", "random" : Math.random()})
db.people.insert({"name" : "jim", "random" : Math.random()})
db.people.find()
var random = Math.random()
result = db.people.findOne({"random" : {"$gt" : random}})
三、索引
(一)特点
- 可以在任意列上建立索引
- 索引的构造和使用与传统关系型数据库几乎一样,适用于Oracle的优化技巧也适用于Mongodb
- 使用索引可以加快查询,但同时会降低修改,插入等的性能
- 内嵌文档照样可以建立使用索引
(二) 建立索引
1、先做一个集合
db.people.insert([
{ "username" : "smith", "age" : 48, "user_id" : 0 },
{ "username" : "smith", "age" : 30, "user_id" : 1 },
{ "username" : "john", "age" : 36, "user_id" : 2 },
{ "username" : "john", "age" : 18, "user_id" : 3 },
{ "username" : "joe", "age" : 36, "user_id" : 4 },
{ "username" : "john", "age" : 7, "user_id" : 5 },
{ "username" : "simon", "age" : 3, "user_id" : 6 },
{ "username" : "joe", "age" : 27, "user_id" : 7 },
{ "username" : "jacob", "age" : 17, "user_id" : 8 },
{ "username" : "sally", "age" : 52, "user_id" : 9 },
{ "username" : "simon", "age" : 59, "user_id" : 10 }
])
2、建立索引
db.people.ensureIndex({"username" : 1}) //1表示是(正向)升序的索引
db.people.ensureIndex({"username" : 1,"age":-1}) //建立复合(组合)索引
explain()函数显示执行计划(执行过程)
db.people.find().explain()

indexFilterSet: false 显示没有使用索引
3、查看索引
查看当前数据库的各集合的索引
db.system.indexes.find()
4、删除索引
db.runCommand({"dropIndexes":"peole","index":"age_1"})
删除people表中名为age_1的索引
db.runCommand({"dropIndexes":"peole","index":*})
删除people表中所有的索引
四、其他操作
(一)、聚合
1、count
查看数据集合中有多少行
db.people.count()
2、distinct
db.runCommand({"distinct" : "people", "key" : "age"})
3、group
分组求和
db.people.group({
"key":{"username":true},
"initial": {"csum": 0 },
"reduce":function(obj, prev)
{
prev.csum += obj.age;
}
})
另外一个例子

doc 是行扫描,prev是记算保存的结果
(二)、把函数当做key
To define a grouping function, you must use a $keyf key (instead of "key"). Using "$keyf" makes the group command look something like this:
db.posts.group({"ns" : "posts",
"$keyf" : function(x) { return x.category.toLowerCase(); },
"initializer" :
})
"$keyf" allows you can group by arbitrarily complex criteria.
(三)、MapReduce
n 与Hadoop的Map-Reduce神似
n 能完成count、distinct、group所能做的一切事情
例子:寻找集合中所有的键
先定义一个map函数
map = function() { for (var key in this) { emit(key, {count : 1});
}};
再定义一个reduce函数
reduce = function(key, emits) {
total = 0;
for (var i in emits) {
total += emits[i].count;
}
return {"count" : total};
}
db.runCommand({"mapreduce" : "people", "map" : map, "reduce" : reduce,"out":"result"})
这个函数的说明 :
{"mapreduce" : "people"意思是在people这个集合中做mapreduce操作
"map" : map, "reduce" : reduce,"指明map函数和reduce函数,
"out":"result" 说明输出到那个集合
最后可以用 db.result.find()来查看来次操作的结果。
(四)、冷备份
关闭mongodb的情况下复制数据目录
(五)热备份
mongodump 出来的json和bson这种形式的文件
mongodump -d db
-o 重新指定dump文件存放位置
备份出来的数据还源
mongorestore -d foo --drop backup/test/
-d foo 表示还原到foo这个数据库中,
--drop backup/test/ 表示把原始的的backup/test/删除了。
(六)、强制一致
use admin //管理数据库
db.runCommand({"fsyns":1,"lock":1}) //把缓冲区的数据全部写到硬盘,然后加一把锁,不让数据再写入进来,
db.$cmd.sys.unlock.findOne();备份完成后解锁。
(七)、修复数据库
修复所有数据库:用带—repair参数启动
db.repairDatabase()
(八)、GridFS
从mogodb存放超过16M的文件
n 用于在数据库里存储二进制大文件
n 可以统一用数据库处理数据,而无需借助外部的文件系统
n 可以利用MongoDB的复制或分片机制,故障恢复和可扩展性较好
n 避免使用文件系统的某些限制(例如linux在同一目录下的文件数限制)
n 避免文件碎片(MongoDB分配空间以2GB作为单位)
GridFS存放的原理
- 文件被分成若干块,每个块作为一个文档存储
- 有一个单独的文档存储分块的信息,以及文件的元数据
- fs.chunks集合存入具体的数据
- fs.files集合 存入元数据
五、完成器
(一)、先完成聚合
db.posts.group({
"key" : {"tags" : true},
"initial" : {"tags" : {}}, //输出的也是tags
"$reduce" : function(doc, prev) {
for (i in doc.tags) {
if (doc.tags[i] in prev.tags) {
prev.tags[doc.tags[i]]++;
}else {
prev.tags[doc.tags[i]] = 1;
}
}
}})
(二)、再用完成器,确定当天最受欢迎的标签
"finalize" : function(prev) {
var mostPopular = 0;
for (i in prev.tags) {
if (prev.tags[i] > mostPopular) {
prev.tag = i;
mostPopular = prev.tags[i];
}
}
delete prev.tags
}}})
mongodb进阶的更多相关文章
- MongoDb进阶实践之六 MongoDB查询命令详述(补充)
一.引言 上一篇文章我们已经介绍了MongoDB数据库的查询操作,但是并没有介绍全,随着自己的学习的深入,对查询又有了新的东西,决定补充进来.如果大家想看上一篇有关MongoDB查询的 ...
- mongodb进阶一之高级查询
上篇文章我们讲了mongodb的crud基本操作 http://blog.csdn.net/stronglyh/article/details/46812579 这篇我们来说说mongodb的进阶-- ...
- MongoDB 进阶模式设计
原文链接:http://www.mongoing.com/mongodb-advanced-pattern-design 12月12日上午,TJ在开源中国的年终盛典会上分享了文档模型设计的进阶技巧,就 ...
- MongoDb进阶实践之一 如何在Linux(CentOS 7)上安装MongoDB
一.NoSQL数据简介 1.NoSQL概念 NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL",是 ...
- MongoDb进阶实践之二 如何在Windows上配置MongoDB
一.引言 上一篇文章,我介绍了如何在Linux系统上安装和配置MongoDB,其实都不是很难,不需要安装和编译,省去了Make && Make Install 命 ...
- MongoDb进阶实践之三 Mongodb基本命令详解
一.引言 从今天开始,我要正式开始介绍MongoDB的使用方法了.在此之前,我用了两篇文章分别介绍了如何在Linux系统和Windows系统上安装和配置MongoDB系统.如 ...
- MongoDb进阶实践之三 MongoDB查询命令详述
一.引言 上一篇文章我们已经介绍了MongoDB数据库的最基本操作,包括数据库的创建.使用和删除数据库,文档的操作也涉及到了文档的创建.删除.更新和查询,当然也包括集合的创建.重命 ...
- MongoDb进阶实践之五 MongoDB修改命令详述
一.引言 上一篇文章我们已经详细介绍了MongoDB数据库的有关查询的内容,但是这只是所有查询命令的冰山一角.所有查询命令都写完也没有必要,我只是写了一些常用的命令,对MongoDB的 ...
- MongoDb进阶实践之七 MongoDB的索引入门
一.引言 好久没有写东西了,MongoDB系列的文章也丢下好长时间了.今天终于有时间了,就写了一篇有关索引的文章.一说到"索引",用过关系型数据库的人都应该知道它是一个什么 ...
随机推荐
- cs231n spring 2017 lecture15 Efficient Methods and Hardware for Deep Learning 听课笔记
1. 深度学习面临的问题: 1)模型越来越大,很难在移动端部署,也很难网络更新. 2)训练时间越来越长,限制了研究人员的产量. 3)耗能太多,硬件成本昂贵. 解决的方法:联合设计算法和硬件. 计算硬件 ...
- Ping pong(树状数组求序列中比某个位置上的数小的数字个数)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2492 Ping pong Time Limit: 2000/1000 MS (Java/Others) ...
- 两句话概括cmd和amd的区别
=== | === | === | ===AMD | 速度快 | 会浪费资源 | 预先加载所有的依赖,直到使用的时候才执行=== | === | === | ===CMD | 只有真正需要才加载依赖 ...
- java中JFrame类中函数addWindowListener(new WindowAdapter)
转自:http://blog.csdn.net/datouniao1/article/details/46984987:侵删. 在java编写的过程中常常遇到样的一段代码: frame.addWind ...
- 【centos6.5 hadoop2.7 _64位一键安装脚本】有问题加我Q直接问
#!/bin/bash#@author:feiyuanxing [既然笨到家,就要努力到家]#@date:2017-01-05#@E-Mail:feiyuanxing@gmail.com#@TARGE ...
- 最近公司用到了lombok,感觉很不错的样子,所以上网搜了一些资料,总结了一下用法。
lombok作用:它提供了简单的注解形式来帮助我们简化消除一些必须有但显得很臃肿的Java代码,特别是相对于 POJO.缺点是使用lombok虽然能够省去手动创建setter和getter方法的麻烦, ...
- php 使用 ffmpeg 转换视频,截图,并生成缩略图
http://blog.csdn.net/toss156/article/details/7003059 把ffmpeg 和 生成缩略图整合了一下. include("ImageResiz ...
- JavaScript之事件委托(附原生js和jQuery代码)
事件委托的原理依赖于事件冒泡,可以通过给父元素的事件委托来确定是哪个子元素触发了事件从而做一系列操作. 使用事件委托的优点 1.操作子元素时不用一一遍历,可以根据事件触发的对象而进行相应操作 dom结 ...
- 【开发技术】java+mysql 更改表字段的步骤
1).首先通过SQL更改MYSQL库中的表结构(下面是一些例子) ALTER TABLE `illegalactivate` ADD `macethaddress` varchar(250) NOT ...
- J.U.C FutureTask之源码解析
通过直接继承Thread, 实现Runnable接口来创建线程.但这两种方式都有一种缺陷:在执行完任务之后无法获得执行结果. 如果需要获得执行结果,就必须通过共享变量或者使用线程通信的方式来达到效果, ...