Mongodb学习笔记速记(二)

本文介绍 MongoDB 中的分页、排序、游标、索引、Count/Distinct/Group 等核心操作,以及数据库命令执行、固定集合特性等内容,通过实例深入探讨其在数据查询与管理中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

七.   分页与排序

1.      limit 返回指定的数据条数

//查询出persons文档中前5条数据

db.persons.find({},{_id:0,name:1}).limit(5)

2.      skip 返回指定数据的跨度

//查询出persons文档中5至10条的数据

db.persons.find({},{_id:0,name:1}).limit(5).skip(5)

3.      sort 返回按照年龄排序的数据[1,-1]

db.persons.find({},{_id:0,name:1}).limit(5).skip(5).sort({age:1})//1为正序

db.persons.find({},{_id:0,name:1}).limit(5).skip(5).sort({age:-1})//-1为倒序

注: mongodb的key可以存不同类型的数据,排序也有优先级

最小值->null->数字->字符串->对象/文档->数组->二进制->对象ID->布尔值->日期->时间戳->正而->最大值

(建议:设计时统一数据类型)

4.      limit和skip完成分页

//每页三条数据

第一页:db.persons.find({},{_id:0,name:1}).limit(3).skip(0)

第二页:db.persons.find({},{_id:0,name:1}).limit(3).skip(3)

//skip会影响性能,尽量要少用,可以换个思路

_id    name  age   date

001    Jim    25   2015-11-03:12:54:25

002    Tom   34   2015-11-04:12:20:25

003    Lili     21   2015-11-05:12:14:25

004    Zhang  23   2015-10-03:12:34:25

005    Wang  26   2015-10-03:12:20:25

006    Zhao   29   2015-09-03:12:29:25

*每次查询操作的时候,前后台传值要把上次的最后一个文档的日期保存下来

db.persons.find({date:{$gt:日期数值}}).limit(3)

(另:应该把重点放在便捷和精确查询上,而不是分页的性能,因为用户一般不会翻查2页))

 

 

八.   游标

1.      利用游标遍历查询数据,游标只读取一遍

varpersons=db.persons.find();

while(persons.hasNext()){

           obj=persons.next();

           print(obj.name)

}

 

2.      游标销毁条件:1.客户端发来信息要销毁,2.游标迭代完毕,3.默认游标超过10分钟没使用

3.      查询快照 $snapshot:true

快照后就会针对不变的集合进行游标运动,使用快照可以不修改原来的集合,避免修改后的数据出现混乱

db.persons.find({$query:{name:”Jim”},$snapshot:true})

九.   索引

1.      创建索引

数据准备 index.js

~~for(vari=0;i<200000;i++){

            db.books.insert({number:i,name:i+”book”})

}

   ////20万数据,差不多用时7秒

  先检验查询性能

  var start=new Date()

  db.books.find({number:65871}) //查询65871条数据

  var end=new Date()

  end-start

//用时102毫秒

  为number创建索引

db.books.ensureIndex({number:1})

再输入查询65871条数据,用时12毫秒

2.      索引使用注意

db.books.ensureIndex({number:1})

1  为正序创建索引

-1 为倒序创建索引

2.1 创建索引可以提高查询性能,但影响插入性能所以对于多查少插的文档可以考虑使用

2.2 全键都建索引不一定能提高性能

2.3做排序工作如果数据量大可以加索引,提高排序性能

3.  索引的名称

         3.1用VUE查看索引名称

            //number:1

3.2  创建索引同时指定索引的名字

db.books.ensureIndex({name:-1},{name:”bookname”})

4.      唯一索引

4.1  解决文档books不能插入重复的数值

建立唯一索引后不能再插入重复的数值

db.books.ensureIndex({name:1},{unique:true})//建立索引

试验

db.books.find({name:”0book”}) ///能找到

db.books.insert({name:”0book”})  ///报错

5.      踢出重复值

如果创建唯一索引前,已有重复数据, dropDups:true会自动删除重复的索引

db.books.ensureIndex({name:-1},{unique:true,dropDups:true})

6.      Hint

强制查询指定的索引

db.books.find({name:”1book”,number:1}).hint({name:-1})

指定索引必须是已经创建了的索引,正序用1查,倒序用-1查

7.      expain

详细查看本次查询使用的索引和查询数据的状态信息

db.books.find({name:”1book”}).explain()

// “cursor”:”BtreeCursorname_-1” 本次查询使用的索引

//”nscanned”:1  查询的文档数目

//”millis”:0     查询消耗的时间, 0是很不错的性能

8.      索引管理

8.1  system.indexes 在shell查看数据库已经建立的索引

db.system.indexes.find()

db.system.namespaces.find()//查询出来的不是一个集合

8.2  后台执行 执行创建索引的过程会暂时锁表,所以为了不影响执行,可以设置在后台执行索引的创建过程

db.books.ensureIndex({name:-1},{background:true})

8.3  删除索引

批量和精确删除索引( runCommand可以执行任何特殊命令)

db.renCommand({dropIndexes:”books”,index:”name_-1”})//精确删除

db.runCommand({dropIndexes:”books”,index:”*”})  //批量删除

 

十.   空间索引

1.      利用空间索引查询地理坐标

数据准备 map.json  //gis[x,y]

1.1  查询出距离点(70,180)最近的3个点

//添加2D索引

db.map.ensureIndex({“gis”:”2d”},{min:-1,max:201})

//如不写坐标,默认会建立一个[-180,180]之间的2D索引

查询点(70,180)最近的3个点

db.map.find({“gis”:{$near:[70,180]}},{gis:1,_id:0}).limit(3)

1.2  查询以点(50,50)和点(190,190)为对角线的正方形中的所有的点

db.map.find({gis:{“$within”:{$box:[[50,50],[190,190]]}}},{_id:0,gis:1})

1.3  查询以圆心为(56,80)半径为50规则下的圆心面积中的点

db.map.find({gis:{$within:{$center:[[56,80],50]}}},{_id:0,gis:1})

十一.  Count + Distinct + Group

1.      Count 计数

//请查询persons美国学生的人数

//db.persons.find().count()总人数

db.persons.find({country:”USA”}).count()

2.      Distinct 不同/过滤相同值/去重

//请查询persons中一共有多少个国家,分别是什么

db.runCommand({distinct:”persons”,key:”country”}).values

3.      Group 分组

语法:

db.runCommand({group:{

           ns:集合名字,

           key:分组的键对象,

           initial:初始化累加器,

           $reduce:组分解器,  //

           condition:条件,

           finalize:组完成器

}})

//分组首先会按照key进行分组,每组的每一个文档都要执行$reduce方法

//接收两个参数,一个是组内本条记录,一个是累加器数据

3.1 请查出persons中每个国家数学成绩最好的学生(必须90以上)

//$reduce分解器

//先把国家分组,再对比数学成绩

db.runCommand({group:{

                  ns:”persons”,

                  key:{“country”:true},

                  initial:{m:0},

                  $reduce:function(doc,prev){   //分解器,分开对比,累加

                           If(doc.m>prev.m){

                                     prev.m=doc.m;

                                     prev.name=doc.name;

                                     prev.country=doc.country;

}

},

condition:{m:{$gt:90}}    /////设定条件,过滤

}})

3.2  在3.1要求的基础上把每个人的信息连接起来写一个描述赋值到m上

// finalize 完成器

db.runCommand({group:{

                   ns:”persons”,

                   key:{“country”:true},

                   initial:{m:0},

                   $reduce:function(doc,prev){   //分解器,分开对比,累加

                            If(doc.m>prev.m){

                                     prev.m=doc.m;

                                     prev.name=doc.name;

                                     prev.country=doc.country;

}

},

finalize:function(prev){  //完成器,用m代替原有的长字符串

           prev.m=prev.name+”Mathscores”+prev.m

},

condition:{m:{$gt:90}}    /////设定条件,过滤

}})

4.      用函数格式化分组的键

4.1 如果集合中出现键country 和counTry同时存在,那么分组就会麻烦,

//$keyf

db.runCommand({group:{

           ns:”persons”,

                            $keyf:function(doc){

                                     If(doc.counTry){

                                               return{country:doc.counTry}

}else{

         return{country:doc.country}

}

},

Initial:{m:0},

$reduce:function(doc,prev){

         If(doc.m>prev.m){

                   prev.m=doc.m;

                   prev.name=doc.name;

                   if(doc.country){

                            prev.country=doc.country;

}else{

         prev.country=doc.counTry;

}

}

},

           finalize:function(){

                    prev.m=prev.name+”Math  scores”+prev.m

},

condition:{m:{$gt:90}}

}})

                  

十二. 数据库命令操作

1.      命令执行器 runCommand

1.1  用命令执行完成一次删除表的操作

//删除map

db.runCommand({drop:”map”}){

            “nIndexesWas”:2,

            “msg”:”indexes dropped forcollection”,

            “ns”:”foobar.map”,

            “ok”:1

}

2.      如何查询mongoDB为我们提供的命令

2.1  在shell 中执行 db.listCommands()

2.2  访问网址API http://localhost:28017/_commands

//需要在启动项(mongodb.bat)配置—rest

mongod --dbpathD:\MongodbData --rest

//27017 + 1000 =28017

3.      常用命令举例

3.1查询服务器版本号和主机操作系统

db.runCommand({buildInfo:1})  //

3.2 查询执行集合的详细信息,大小,空间,索引等…

db.runCommand({collStats:”persons”})

3.3 查看操作本集合最后一次错误信息

db.runCommand({getLastError:”persons”})

 

十三. 固定集合特性

1.      概念:给集合指定大小,数量,增加一个,在未尾弹出一个(栈:先进后出)

2.      固定特性

2.1  固定集合默认是没有索引的,就算是_id也是没有索引的

2.2  由于不需分配新的空间,他插入的速度非常快

2.3  固定集合的顺序是确定的,导致查询速度也非常快

2.4  最适合的应用就是日志管理

3.      创建固定集合

3.1  创建一个新的固定集合,要求大小是100个字节,可以存储文档10个

db.createCollection(“mycoll”,{size:100,capped:true,max:10})

//mycoll 固定集合名称, capped封闭

3.2  把一个普通集合转换成固定集合

db.runCommand({converToCapped:”persons”,size:100000})

//persons要转换的集合

4.      反向排序,默认的插入顺序排序

4.1  查询固定集合mycoll并且反向排序

db.mycoll.find().sort({$natural:-1})

5.      尾部游标,可惜shell不支持,  java和php等驱动是支持的

5.1 尾部游标概念: 这是个特殊的只能用到固定级的游标,它在没有结果的时候也不会自动销毁,直到结果的出现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值