Mongodb基本的原则是:条件句是内层文档的键,修改器是外层文档的键【即,修改器要修改的字段声明在修改器内部】。
1、$size,用于查询数组大小为size的记录

db.a.find({"comments":{"$size":3}})
表示查询comments数组中含有三个元素的记录。
既然size可以查询指定数组大小的记录,那么,如果在文档中增加一个size字段,就可以使用 $gt和$lt等比较操作符来进行查询了。
比如说我们增加了一个size字段,表示目前comments中含有的评论个数,那么在查询的时候就可以使用
db.a.find({"size":{"$gt":3}})
这样就能查询出来comment个数大于3个的了。
记得维护size的数据哦,更新comments数据的时候,同时更新size字段
db.a.update({},{"$push":{"cmt":"another comment!"},"$inc":{"size":1}})
2、删除记录中的一个字段
db.a.update({},{"$unset":{"addrs":1}})
3、$push向数组中增加一个元素,如果数组不存在则创建
db.a.update({},{"$push":{"addrs":"shenzhen"}})
4、从数组中删除一个
$pop
db.a.update({},{"$pop":{"addrs":-1}})
-1表示从数组末尾删除。
db.a.update({},{"$pop":{"addrs":1}})
1表示从数组头部删除
$pull
$pull可以删除指定的数组元素
db.a.update({},{"$pull":{"addrs":"shenzhen"}})
5、给已存在的对象增加一个键值或修改一个键值
db.a.update({},{"$set":{"addrs":['shenzhen','guangzhou']}})
6、查询一个数组的最前n、最后n个元素
db.a.find({},{"addrs":{"$slice":5}})
这里查询了一条记录中地址中的前5个。后5个可以用-5。并且,slice也支持偏移和要返回的数据量

db.a.find({},{"addrs":{"$slice":[5,10]}})上面的语句查询了从第6条数据开始,一共10条数据,如果从第六条数据开始,后面不足10条,那么返回后面的所有元素。

7、skip

使用Mongodb的时候【其他数据库也类似】,尽量少跳过过多的数据,这样会产生性能问题。
mongodb的skip是用来跳过数据的,但是要少用。需要使用的时候可以用其他方式代替。比如说要对博客文章分页,那么一般的做法是
db.a.find().sort({"time":1}).skip(10000).limit(10)
优化的做法可能是,根据上一页取出来的时间,在下次分页,即取出下一页的时候,根据上一个时间,来查找,然后再limit,例如
db.a.find({"time":{"$gt":lasttime}}).sort({"time":1})..limit(10)
这样用查找替代跳过数据,效率会有提升。

8、有一个需求是从一个collection中随机选取出一个文档。

那么一般的做法是,先统计文档总数count,然后生成一个1到count的数字,去数据库中取出这个数字对应的文档。

这种方法是很低效的。要统计count,然后才能取出来数据。

高效的做法是:在存储数据的时候,同时存储一个random字段。
每次插入一个记录的时候,都生成一个随机数字赋值给这个字段。那么在随机选取一个文档的时候,这样就可以生成一个随机数rand,然后找到比这个随机数大的一个文档:
result=db.a.findOne({"random":{"$gt":rand}})
if result == null
    result=db.a.findOne({"random":{"$gt":rand}})

这样如果最后result还是null,说明数据库中是没有记录了。随机取出一个文档的任务也完成了。

9、删除索引

db.a.dropIndex("indexname")

其中的indexname可以在system.index集合中查找。

10、查询内嵌文档

例如有如下文档:

{"content":"this is content","comments":[{"author":"naughty","score":3},{"author":"cc","score":4}]}

现在要查询author是naughty并且naughty的评论score大于3的记录,那么首先想到的查询是这样的:

db.a.find({'comments.author':'naughty'},{'comments.score':{$gt:3}})

但是记录多起来,查询的时候会发现,这样写是不对的。这样写,只要comments中有naughty并且有score是大于3,那么就会查询出来这条记录。查询结果不是我们想要的。

“要正确的指定一组条件,而不是单独的指定每个键。”书上如是说。

要这样写查询:

db.a.find({"comments":{"$elemMatch":{"author":"naughty","score":{"$gt":3}}}})这样就对了。

elemMatch将限定条件进行分组,仅当需要对一个内嵌文档的多个键进行查询的时候,才会用到。

11、group

假设有类似的一个需求:

有几条这样的文档

db.d.insert({"day":"2012-9-9","tags":['a','b','c','d']})
db.d.insert({"day":"2012-9-9","tags":['c','d']})
db.d.insert({"day":"2012-9-9","tags":['a','d']})
db.d.insert({"day":"2012-9-10","tags":['a','b']})
db.d.insert({"day":"2012-9-10","tags":['a','d']})

要查询每一天tags中出现次数最多的那个tag是什么。那么查询可以按照如下进行:

db.d.group({"key":{"day":true},"initial":{"tags":{}},"reduce":function(doc,res){
    for(i in doc.tags){
        if(doc.tags[i] in res.tags){
            res.tags[doc.tags[i]]++;
        }else{
            res.tags[doc.tags[i]]=1;
        }
    }
},
"finalize":function(res){
    var mp=0;
    for(i in res.tags){
        if(res.tags[i]>mp){
            res.tag=i
            mp=res.tags[i];
        }
    }
    delete res.tags
}
})

其中finalize是在group动作结束之后,对聚合的每一个组调用一次。reduce函数是在聚合的时候进行调用,是用来生成分组的。reduce函数的两个参数分别是:当前文档和本组当前的聚合结果。

12、分片

分片【sharding】的目的是为了提高存储性能,那么什么时候进行分片呢?

第一、机器磁盘不够用了。

第二、机器已经不能满足写数据的性能需求。

第三、想把大数据都放在内存中以提高性能。

mongos就是mongodb的各个版本中都配备的路由器进程,它路由所有的请求,然后将结果聚合。它本身并不存储数据或者是配置信息(但是会缓存配置服务器的信息)。配置服务器存储了集群的配置信息:数据和片的对应关系。

Mongodb使用的更多相关文章

  1. 【翻译】MongoDB指南/聚合——聚合管道

    [原文地址]https://docs.mongodb.com/manual/ 聚合 聚合操作处理数据记录并返回计算后的结果.聚合操作将多个文档分组,并能对已分组的数据执行一系列操作而返回单一结果.Mo ...

  2. 【翻译】MongoDB指南/CRUD操作(四)

    [原文地址]https://docs.mongodb.com/manual/ CRUD操作(四) 1 查询方案(Query Plans) MongoDB 查询优化程序处理查询并且针对给定可利用的索引选 ...

  3. 【翻译】MongoDB指南/CRUD操作(三)

    [原文地址]https://docs.mongodb.com/manual/ CRUD操作(三) 主要内容: 原子性和事务(Atomicity and Transactions),读隔离.一致性和新近 ...

  4. 【翻译】MongoDB指南/CRUD操作(二)

    [原文地址]https://docs.mongodb.com/manual/ MongoDB CRUD操作(二) 主要内容: 更新文档,删除文档,批量写操作,SQL与MongoDB映射图,读隔离(读关 ...

  5. 【翻译】MongoDB指南/CRUD操作(一)

    [原文地址]https://docs.mongodb.com/manual/ MongoDB CRUD操作(一) 主要内容:CRUD操作简介,插入文档,查询文档. CRUD操作包括创建.读取.更新和删 ...

  6. CRL快速开发框架系列教程十二(MongoDB支持)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  7. MongoDB系列(二):C#应用

    前言 上一篇文章<MongoDB系列(一):简介及安装>已经介绍了MongoDB以及其在window环境下的安装,这篇文章主要讲讲如何用C#来与MongoDB进行通讯.再次强调一下,我使用 ...

  8. MongoDB系列(一):简介及安装

    什么是MongoDB MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统. 在高负载的情况下,添加更多的节点,可以保证服务器性能. MongoDB 旨在为应用提供可扩展的高 ...

  9. [原]分享一下我和MongoDB与Redis那些事

    缘起:来自于我在近期一个项目上遇到的问题,在Segmentfault上发表了提问 知识背景: 对不是很熟悉MongoDB和Redis的同学做一下介绍. 1.MongoDB数组查询:MongoDB自带L ...

  10. 用MongoDB分析合肥餐饮业

    看了<从数据角度解析福州美食>后难免心痒,动了要分析合肥餐饮业的念头,因此特地写了Node.js爬虫爬取了合肥的大众点评数据.分析数据库我并没有采用MySQL而是用的MongoDB,是因为 ...

随机推荐

  1. cobbler部署

    1.cobbler介绍 Cobbler是一个快速网络安装linux的服务,而且在经过调整也可以支持网络安装windows.该工具使用python开发,小巧轻便(才15k行python代码),使用简单的 ...

  2. Errors occurred during the build. Errors running builder 'DeploymentBuilder' on project '项目名'

    问题描述: Errors occurred during the build. Errors running builder 'DeploymentBuilder' on project 'myf'. ...

  3. Timestamp的作用及与字符串的相互转换 .

    一.Timestamp的介绍 每一个数据库都有一个计数器,这个计数器记录着数据行的插入.更新行为.如果我们为一个表中增加 timestamp 列,那么,该列将记录每一个数据行的计数器值.假如数据库中当 ...

  4. 如何使用SC命令添加删除服务

    1.如何删除服务 cmd然后再输入 sc delete "服务名称" 后,回车,双引号必须为英文符号. 2.添加服务 sc create ServiceName binPath= ...

  5. ios 系统参数用法

    qi前言:写一个宏来选择性地编译与运行为不同iOS所写的代码来支持多个版本的ios工程 #if __IPHONE_OS_VERSION_MIN_REQUIRED #import "xxxxx ...

  6. linux修改主机名(hostname)转载

    Linux修改主机名的方法 用hostname命令可以临时修改机器名,但机器重新启动之后就会恢复原来的值. #hostname   //查看机器名#hostname -i  //查看本机器名对应的ip ...

  7. 节点的创建--对比jQuery与JavaScript 方法

    一.  创建节点: 节点是DOM结构的基础,根据DOM规范,节点是一个很宽泛的概念,包含元素.属性.文本.文档和注释.但在实际开发中,要动态创建内容,主要操作的节点包括元素.属性和文本. 1.需求:创 ...

  8. java新手笔记18 类比较

    1.Shap类 package com.yfs.javase; public class Shape /*extends Object */{ //默认继承object object方法全部继承 // ...

  9. 执行mysql脚本

    方法1: mysql -uroot -p123456 -Ddatabasename < sql文件路径 方法2: source 路径全名 \. 路径全名

  10. 如何在Angular2中使用Forms

    在Angular2中形成两个基本对象是Control和ControlGroup. 控制用户输入 Control 一个控制表示一个输入字段(ngFormControl) 一个控制可以绑定到一个input ...