当前位置:网站首页 / 数据库 / 正文

[AY-Mongo 3.x]写给自己的MongoDB笔记-深入浅出聚合管道与拾遗【3/3】[8]

时间:2015年11月06日 | 作者 : aaronyang | 分类 : 数据库 | 浏览: 1300次 | 评论 0

2015年11月6日     www.ayjs.net独家拥有,未经许可,不许转载,违者追究法律责任

管道优化

1.$sort  +  $skip  +  $limit顺序优化

如果在执行管道聚合时,如果$sort、$skip、$limit依次出现的话,例如:

{ $sort: { age : -1 } },

{ $skip: 10 },

{ $limit: 5 }


那么实际执行的顺序为:

{ $sort: { age : -1 } },

{ $limit: 15 },

{ $skip: 10 }

$limit会提前到$skip前面去执行。

此时$limit = 优化前$skip+优化前$limit

这样做的好处有两个:1.在经过$limit管道后,管道内的文档数量个数会“提前”减小,这样会节省内存,提高内存利用效率。2.$limit提前后,$sort紧邻$limit这样的话,当进行$sort的时候当得到前“$limit”个文档的时候就会停止。


2.$limit + $skip + $limit + $skip Sequence Optimization

如果聚合管道内反复出现下面的聚合序列:

  { $limit: 100 },

  { $skip: 5 },

  { $limit: 10},

  { $skip: 2 }

首先进行局部优化为:可以按照上面所讲的先将第二个$limit提前:

  { $limit: 100 },

  { $limit: 15},

  { $skip: 5 },

  { $skip: 2 }

进一步优化:两个$limit可以直接取最小值 ,两个$skip可以直接相加:

 { $limit: 15 },

 { $skip: 7 }


3.Projection Optimization

过早的使用$project投影,设置需要使用的字段,去掉不用的字段,可以大大减少内存。除此之外也可以过早使用

我们也应该过早使用$match、$limit、$skip操作符,他们可以提前减少管道内文档数量,减少内存占用,提供聚合效率。

除此之外,$match尽量放到聚合的第一个阶段,如果这样的话$match相当于一个按条件查询的语句,这样的话可以使用索引,加快查询效率


管道限制

    1.类型限制

在管道内不能操作 Symbol, MinKey, MaxKey, DBRef, Code, CodeWScope类型的数据( 2.4版本解除了对二进制数据的限制).

    2.结果大小限制

管道线的输出结果不能超过BSON 文档的大小(16M),如果超出的话会产生错误.

    3.内存限制

如果一个管道操作符在执行的过程中所占有的内存超过系统内存容量的10%的时候,会产生一个错误。

当$sort和$group操作符执行的时候,整个输入都会被加载到内存中,如果这些占有内存超过系统内存的%5的时候,会将一个warning记录到日志文件。同样,所占有的内存超过系统内存容量的10%的时候,会产生一个错误


聚合管道支持在已分片的集合上进行聚合操作。当分片集合上进行聚合操纵的时候,聚合管道被分为两成两个部分,分别在mongod实例和mongos上进行操作。





一些$操作的遗漏

匹配null值

db.students.find({"classroom.grade":null})

blob.png

效果图

blob.png



数组查询

我手动修改了最后一个爱好

blob.png

变成了写代码


①数组内容匹配

db.students.find({"hobby":"写代码"})

blob.png

但是 db.students.find({"hobby":["写代码","逛街","看电影","羽毛球"]})写是没用的

可以使用$all,里面的值的顺序无关,$all类似mssql的 all用法,全部都要满足,相对应的是$in 任意一个满足

db.students.find({"hobby":{"$all":["写代码","逛街","看电影","羽毛球"]}})

blob.png

blob.png

blob.png

新增一个hobby只有2个值的文档

{"name":"ayui",age:1,city:'hf',province:'ah',hobby:["更新","免费"]}

blob.png

使用$size根据 数组值的数量的大小查询

db.students.find({'hobby' : {'$size' : 2}})

blob.png

$size不能和类似 > <==等等的运算符使用

blob.png

$slice 两个参数分别是偏移量和返回的数量

db.students.find({},{"hobby":{"$slice":[1,1]}})

$slice[x,y],x从0开始,表示不跳过元素,1代表跳过1个元素,y代表返回几个元素

blob.png



查询直接写js

db.students.find("this.age==23")

blob.png


找偶数的年龄的用户

db.students.find("this.age%2==0")

blob.png

等效于

db.students.find({age:{ $mod:[2,0]}})

效果图如上,不发了。



$exists用来判断一个元素是否存在

db.students.find({ sex : { $exists : true}}); // 如果存在元素sex,就返回

db.students.find({ sex : { $exists : false}}); // 如果不存在元素sex,就返回

sex存在就返回,第一条由于不存在,所以不返回,然后判断是否存在age,存在就返回了数据。

blob.png


2015年11月6日     www.ayjs.net独家拥有,未经许可,不许转载,违者追究法律责任

$type 基于 bson type来匹配一个元素的类型,像是按照类型ID来匹配

db.students.find( { age : { $type : 16 } } );

blob.png16是数字,2是string

blob.png

2015年11月6日     www.ayjs.net独家拥有,未经许可,不许转载,违者追究法律责任


$elemMatch 如果对象有一个元素是数组,那么$elemMatch可以匹配内数组内的元素

新增一个集合的数据,主要需要二维数组

var a={"content":"this is content","comments":[{"author":"naughty","score":3},{"author":"cc","score":4}]};
db.testBlog.save(a);

blob.png


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

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

而且这个语句也不对。。。这个毕竟查集合中的数组,而且也不是 完整的一组条件

使用$elemMatch

db.testBlog.find({"comments":{"$elemMatch":{"author":"naughty","score":{"$gt":2}}}})

blob.png



$push

用法:{ $push : { field : value } }

把value追加到field里面去,field一定要是数组类型才行,如果field不存在,会新增一个数组类型加进去。

比如我们给名字是杨洋的,增加一个新的爱好 :玩英雄联盟

db.students.update({"name":"杨洋"},{$push:{"hobby":"玩英雄联盟"}})

blob.png

blob.png

增加一个数组

db.students.update({"name":"杨洋"},{$push:{"hobby":["巨神峰","AYZBanana丶"]}})

blob.png

blob.png

增加一个没有的key的数组

db.students.update({"name":"杨洋"},{$push:{"sports":["爬山","羽毛球","拳击"]}})

blob.png

$pushAll     追加多个值到一个数组

db.students.update({"name":"杨洋"},{$pushAll:{"sports":["爬山2","羽毛球2","拳击2"]}})

blob.png

继续执行下,看看会不会继续重复增加

db.students.update({"name":"杨洋"},{$pushAll:{"sports":["爬山2","羽毛球2","拳击2"]}})

blob.png

答案是重复增加了


2015年11月6日     www.ayjs.net独家拥有,未经许可,不许转载,违者追究法律责任


$addToSet 增加一个值到数组内,而且只有当这个值不在数组内才增加

db.students.update({"name":"杨洋"},{$addToSet:{"sports":{$each:["爬山2","羽毛球3","拳击3"]}}})

blob.png

发现 爬山2没有增加进去,因为已经存在。


如果没有$each,则把它当做整体加进去了

db.students.update({"name":"杨洋"},{$addToSet:{"sports":["爬山2","羽毛球3","拳击3"]}})

blob.png

blob.png

$pop删除数组内的一个值

用 法:

删除最后一个值:{ $pop : { field : 1 } }删除第一个值:{ $pop : { field : -1 } }

删除第一个值

db.students.update({"name":"杨洋"},{$pop:{"hobby":-1}})

原来

blob.png

现在:

blob.png


$pull

用法:$pull : { field : value } }

从数组field内删除一个等于value值。

db.students.update({"name":"杨洋"},{$pull:{"hobby":"逛街"}})

原来

blob.png

现在

blob.png


$pullAll

用法:{ $pullAll : { field : value_array } }

同$pull,可以一次删除数组内的多个值

原来

blob.png

执行:

db.students.update({"name":"杨洋"},{$pullAll:{"sports":[["爬山2","羽毛球3","拳击3"],"爬山2"]}})

现在

blob.png

发现他删除的是全部的    “爬山2”,本来有2个的,还删除了可以是数组的。



$操作符   表示符合条件的自己,按条件找出的数组里面的,某一项,就是他自己,然后就不找了

类似一个 自己的替代符号,因为前面条件查询出了自己,然后被复制给$,然后$就是那个符合条件的值

这是原来的

blob.png

db.testBlog.update({"comments.author":"cc"},{"$set":{"comments.$.score":5}})

blob.png

blob.png

我们继续增加一个叫cc的author,数组加值,用$addToSet

db.testBlog.update({},{"$addToSet":{"comments":{"author":"cc","score":7}}})

blob.png

然后,score加10

db.testBlog.update({"comments.author":"cc"},{"$inc":{"comments.$.score":10}})

blob.png

因为$,标记后,只处理数组中的第一个,如果去掉$,运行,竟然报错了。

db.testBlog.update({"comments.author":"cc"},{"$inc":{"comments.score":10}})

blob.png

那如果我就想数组中每个叫cc的都加10 呢?

db.testBlog.update({"comments.author":"cc"},{"$set":{"comments.score":{$add:10}}})

上面的写法不行

mongo 的 $ 操作符指代的是第一个匹配到的数组元素,所以只能替换一个数组对象,如果要对内嵌数组的所有匹配对象都进行修改,目前可以通过查询出来修改再写入的方式,暂时没有可以直接实现这个功能的操作符



1、现有表以及数据添加字段

  db.tbGoodsConsultant.update({}, {$set:{nFlagState:0}}, false, true);

2、给表字段添加索引

  db.tbGoodsConsultant.ensureIndex({nFlagState:1});



删除表、数据库

  > db.users.drop();

  > db.dropDatabase();


2015年11月6日     www.ayjs.net独家拥有,未经许可,不许转载,违者追究法律责任

推荐您阅读更多有关于“mongodb,”的文章

猜你喜欢

额 本文暂时没人评论 来添加一个吧

发表评论

必填

选填

选填

必填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

  查看权限

抖音号:wpfui,可以看到我的很多作品效果

AYUI8社区版Github地址:前往获取

作者:杨洋(AaronYang简称AY,安徽六安人)目前是个人,还没公司AY唯一QQ:875556003和AY交流

高中学历,2015年1月17日开始,兴趣学习研究WPF

声明:AYUI7个人与商用免费,源码可购买。部分DEMO不免费.AY主要靠卖技术服务挣钱

不是从我处购买的ayui7源码,我不提供任何技术服务,如果你举报从哪里买的,我可以帮你转正为我的客户,并送demo

查看捐赠

AYUI7.X MVC教程 更新如下:

第一课 第二课 程序加密教程

兼容XP到win10,vs2015/2019,最新AYUI:7.6.5.2

vs2015 企业版密钥HM6NR-QXX7C-DFW2Y-8B82K-WTYJV

vs2017 企业版密钥NJVYC-BMHX2-G77MM-4XJMR-6Q8QF

标签列表