• MongoDB入门与实战-第三章-数据操作增删改查索引


    目录

    参考

    https://github.com/Vacricticy/mongodb_practice
    MongoDB之索引

    官方文档

    https://docs.mongodb.com/docs/manual/reference/update-methods/

    表结构

    新增字段

    db.collection.update(criteria,objNew,upsert,multi)
    # demo
    db.device.update({}, {$set: {projectId:"1584383990662078466"}}, {multi: 1})
    # 1 、添加一个字段.  table 代表表名 , 添加字段 content,字符串类型。
    
    db.table.update({}, {$set: {content:""}}, {multi: 1})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    参数说明:

    • criteria:查询条件
    • objNew:update对象和一些更新操作符
    • upsert:如果不存在update的记录,是否插入objNew这个新的文档,true为插入,默认为false,不插入。
    • multi:默认是false,只更新找到的第一条记录。如果为true,把按条件查询出来的记录全部更新。

    修改表字段重命名

    db.getCollection("device").update({}, {$rename : {"code":"deviceCode", "name":"deviceName"}}, false, true)
    xx版本之后使用update和updateOne只能更新满足条件的一条文档。
    
    例子,将原来的字段名raw_field修改成新的字段名new_field。
    
    db.Test.update({}, {'$rename': {'raw_field': 'new_field}}, false, true)
    # 或者
    db.Test.updateOne({}, {'$rename': {'raw_field': 'new_field}}, false)
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    其实上面的update语句中:

    • {}:是过滤条件。(更新哪些文档);
    • {’$rename’: {‘raw_field’: 'new_field}}:是更新操作;
    • false:若根据该过滤条件无法找到匹配的文档时,不插入该文档。
    • true:更新多条(但是我在用这个的时候不太好使,还是用的updateMany来更新的多条)。

    删除字段

    db.url.update({}, {$unset:{'content':''}},false, true)
    
    • 1

    基础操作

    # 查看所有的数据库
    show dbs 或show databases
    # 切换到指定的数据库
    use xxx
    # 查看当前操作的数据库
    db
    # 查看当前数据库中所有的集合
    show collections
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    插入数据

    insert

    
    db.collectionName.insert(  {name:'liu5'} )
    db.collectionName.insert( [ {name:'liu5'} , {name:'liu6'} ] )
    db.user insert({
    	"_id": "11",
    	"name":"zhangsan",
    	"age":18,
    	"hobbies":["music","read"],
    	"addr":{
    		"country":"China",
    		"city":"BJ"
    	}
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    insertOne

    当我们向集合插入一个或多个文档时,如果没有指定_id,则mongodb会自动生成,该属性用来作为文档的唯一标识

    # 插入一条数据
    db.collectionName.insertOne( {name:'liu'} )
    # db表示的是当前操作的数据库
    collectionName表示操作的集合,若没有,则会自动创建
    # 插入的文档如果没有手动提供_id属性,则会自动创建一个
    
    • 1
    • 2
    • 3
    • 4
    • 5

    insertMany

    ## 插入多条数据
    db.collectionName.insertMany( [ {name:'liu5'} , {name:'liu6'} ] )
    db.collectionName.insert( [ {name:'liu5'} , {name:'liu6'} ] )
    需要用数组包起来
    万能API:db.collectionName.insert()
    #添加两万条数据
    for(var i=0;i<20000;i++){
    	db.users.insert({username:'liu'+i}) #需要执行20000次数据库的添加操作
    }
    db.users.find().count()//20000
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    通过数组批量插入

    # 优化:
    var arr=[];
    for(var i=0;i<20000;i++){
    	arr.push({username:'liu'+i})
    }
    db.user.insert(arr) #只需执行1次数据库的添加操作,可以节约很多时间
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    指定自定义id

    db.collectionName.insertOne( {_id:"xxxx",name:'liu'} )
    
    • 1

    在这里插入图片描述

    查询数据

    1、基础查询

    find()

    db.collectionName.find() 或db.collectionName.find({})
    
    查询集合所有的文档,即所有的数据。
    查询到的是整个数组对象。在最外层是有一个对象包裹起来的。
    
    db.collectionName.find({_id:222})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    findOne()

    条件查询。注意:结果返回的是一个数组

    db.collectionName.findOne() 返回的是查询到的对象数组中的第一个对象
    
    • 1

    注意:

    db.students.find({_id:222}).name //错误
    db.students.findOne({_id:222}).name //正确

    # 1.mongodb支持直接通过内嵌文档的属性值进行查询
    # 什么是内嵌文档:hobby就属于内嵌文档
    {
    	name:'liu',
    	hobby:{
    		movies:['movie1','movie2'],
    		cities:['zhuhai','chengdu']
    	}
    }
    
    db.users.find({hobby.movies:'movie1'}) //错误
    db.users.find({"hobby.movies":'movie1'})//此时查询的属性名必须加上引号
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    count()

    db.collectionName.count()或db.collectionName.length() 统计文档个数

    2.查询运算符的使用

    #比较操作符
    $gt 大于
    $gte 大于等于
    $lt 小于
    $lte 小于等于
    $ne 不等于
    $eq 等于的另一种写法
    
    db.users.find({num:{$gt:200}}) #大于200
    db.users.find({num:{$gt:200,$lt:300}}) #大于200小于300
    
    $or 或者
    db.users.find(
        {
            $or:[
                {num:{$gt:300}},
                {num:{$lt:200}}
            ]
        }
    ) #大于300或小于200
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    3.分页查询

    db.users.find().skip(页码-1 * 每页显示的条数).limit(每页显示的条数)
    db.users.find().skip(pageIndex-1 * pageSize).limit(pageSize)
    
    db.users.find().limit(10) #前10条数据
    db.users.find().skip(50).limit(10) #跳过前50条数据,即查询的是第61-70条数据,即第6页的数据
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    4.排序

    db.emp.find().sort({sal:1}) #1表示升序排列,-1表示降序排列
    db.emp.find().sort({sal:1,empno:-1}) #先按照sal升序排列,如果遇到相同的sal,则按empno降序排列
    
    #注意:skip,limit,sort可以以任意的顺序调用,最终的结果都是先调sort,再调skip,最后调limit
    
    #5.设置查询结果的投影,即只过滤出自己想要的字段
    db.emp.find({},{ename:1,_id:0}) #在匹配到的文档中只显示ename字段
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    5、聚合distinct

    # 查询所有的name
    db.user.distinct("name")
    
    • 1
    • 2

    在这里插入图片描述

    6、逻辑与或非

    $and$or$not
    # 1)、select * from user where id>=3 and id<=4
    db.user.find({"_id":{"$gte":3, "$lte":4}})
    
    # 2)、select * from user where id >= 3 and id <= 4 and age >= 4
    db.user.find({
    	"_id":{"$gte":3, "$lte":4}},
    	"age":{"$gte":4}
    )
    # 另一种写法
    db.user.find({
    	"$and":[
    		{"_id":{"$gte":3, "$lte":4}},
    		{"age":{"$gte":4}}
    	]
    })
    
    # 3)、select * from user where id >= 0 and id <= 1 or id >= 4 or name  = 'tianqi'
    db.user.find({
    	"$or":[
    		{"_id":{"$gte":0, "$lte":1}},
    		{"_id":{"$gte":4}},
    		{"name":"tainqi"}
    	]
    })
    
    # 另一种写法
    db.user.find({
    	"$or":[
    		"$and":[
    			{"_id":{"$gte":0}},
    			{"_id":{"$lte":1}}
    		],
    		{"_id":{"$gte":4}},
    		{"name":"tainqi"}
    	]
    })
    
    # 4)、select * from user where id % 2 = 1
    db.user.find({"_id":{"$mod":[2,1]}})
    
    # 5)、上一条取反
    db.user.find({"_id":{"$not":{"$mod":[2,1]}}})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    7、成员运算

    $in $nin
    # 1)、select * from user where age in (1,2,3)
    db.user.find("age":{"$in":[1,2,3]});
    # 1)、select * from user where name not in ('zhangsan', 'lisi')
    db.user.find("age":{"$nin":["zhangsan", "lisi"]});
    
    • 1
    • 2
    • 3
    • 4
    • 5

    8、类型$type

    mongoDB可以使用的类型如下表所示:
    在这里插入图片描述

    # 查询name是字符串类型的数据
    db.user.find({name:{$type:2}})
    
    • 1
    • 2

    9、正则

    正则定义在/ / 内

    # 匹配规则:z开头、n或者u结尾,不区分大小写
    # select * from user where name regexp '^z.*?(n|u)$'
    db.user.find({"name": /^z.*?(n|u)$/i})
    
    • 1
    • 2
    • 3

    10、投影(类似于查询指定列)

    # 查询时,可以在第二个参数的位置来设置查询结果的投影
    # 如下语句只查询ename字段,但是会查出_id, ename两个字段,_id是默认
    db.emp.find({}, {ename:1});
    # 也可以指定不显示_id
    db.emp.find({}, {_id:0, ename:1});
    
    • 1
    • 2
    • 3
    • 4
    • 5

    11、数组

    # 查hobbies中有dancing的人
    db.user.find({"hobbies":"dancing"})
    
    # 查看机油dancing爱好又有tea爱好的人
    db.user.find({"hobbies":{"$all":["dancing", "tea"]}})
    
    # 查看索引第二个爱好为dancing的人(索引从0开始计算)
    db.user.find({"hobbies.1":"dancing"})
    
    # 查看所有人的第1到第2个爱好,第一个{}表示查询条件为所有,第二个显示条件(左闭右开)
    db.user.find({}{
    	"_id":0,
    	"name":0,
    	"age":0,
    	"addr":0,
    	"hobbies":{"$slice":[0,2]}
    })
    
    # 查询所有人最后两个爱好,第一个{}表示查询条件为所有,第二个是显示条件
    db.user.find({}{
    	"_id":0,
    	"name":0,
    	"age":0,
    	"addr":0,
    	"hobbies":{"$slice":-2}
    })
    
    # 查询子文档有"country":"china"的人
    db.user.find({"addr.country":"china"})```
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    12、查询某一天

    方法一、
    db.集合名.find({con_date:new Date("2018-08-13")})
    db.集合名.find({con_date:ISODate("2018-08-13")})
    
    方法二、
    db.集合名.find({con_date:{'$gte':ISODate("2010-12-21"),'$lt':ISODate("2010-12-22")}})
    
    注意:使用gte和lt形式
    
    方法三、
    db.集合名.find({con_date:{'$gte':new Date('2018/08/21 00:00:00'),'$lte':new Date('2018/08/21 23:59:59')}})
    db.集合名.find({con_date:{'$gte':new Date('2018-08-21 00:00:00'),'$lte':new Date('2018-08-21 23:59:59')}})
    
    注意:使用 $gte$lte
    
    方法四、
    db.集合名.find({con_date:ISODate("2018-02-13T16:00:00.000Z")})
    db.集合名.find({con_date:ISODate("2018-08-13")})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    java代码参考:查询mongodb当天数据

    /*
            相差8个时区
            24 = 16 + 8
            db.getCollection("elevator_alarm").find({deviceCode:"1589581864182480897",timestamp:{"$gte":ISODate("2022-11-07T16:00:00.000Z")}}).sort({timestamp:-1})
    
             */
    //mongodb查询条件
    Query query = new Query();
    query.addCriteria(Criteria.where(IotConstant.FIELD_DEVICE_CODE).is(param.getDeviceCode()));
    String todayStr = DateUtil.yesterday().toDateStr();
    Date today = DateUtil.parseDateTime(todayStr+" 00:00:00");
    query.addCriteria(Criteria.where(IotConstant.FIELD_TIMESTAMP).gte(today));
    long count = mongoTemplate.count(query,Dto.class);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    修改数据

    1.替换整个文档

    # db.collectionName.update(condiction,newDocument)
    
    db.students.update({_id:'222'},{name:'kang'})
    
    • 1
    • 2
    • 3

    这种操作会用新对象完全替换旧对象,而不是修改指定属性

    2.修改对应的属性,需要用到修改操作符,比如 s e t , set, set,unset, p u s h , push, push,addToSet

    db.collectionName.update(
    	# 查询条件
    	{_id:222},
    	{
    		#修改对应的属性
    		$set:{ 
    			name:'kang2',
    			age:21
    		}
    		#删除对应的属性
    		$unset:{
    			gender:1 //这里的1可以随便改为其他的值,无影响
    		}
    		
    	}
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    update默认与updateOne()等效,即对于匹配到的文档只更改其中的第一个

    3.updateMany()可以用来更改匹配到的所有文档

    
    db.students.updateMany(
    	{name:'liu'},
    	{
    		$set:{
    			age:21,
    			gender:222
    		}
    	}
    )
    # 使用update也可以实现修改多个
    db.collectionName.update(
    	# 查询条件
    	{_id:222},
    	{
    		#修改对应的属性
    		$set:{ 
    			name:'kang2',
    			age:21
    		}
    		#删除对应的属性
    		$unset:{
    			gender:1 //这里的1可以随便改为其他的值,无影响
    		},{
    			multi: true // 表示修改多个
    		}
    		
    	}
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    4.向数组中添加数据

    db.users.update({username:'liu'},{$push:{"hobby.movies":'movie4'}})
    
    #如果数据已经存在,则不会添加
    db.users.update({username:'liu'},{$addToSet:{"hobby.movies":'movie4'}})
    
    • 1
    • 2
    • 3
    • 4

    5.自增自减操作符$inc

    {$inc:{num:100}} #让num自增100
    {$inc:{num:-100}} #让num自减100
    db.emp.updateMany({sal:{$lt:1000}},{$inc:{sal:400}}) #给工资低于1000的员工增加400的工资
    
    
    • 1
    • 2
    • 3
    • 4

    删除数据

    1. db.collectionName.remove()

    # remove默认会删除所有匹配的文档。相当于deleteMany()
    # remove可以加第二个参数,表示只删除匹配到的第一个文档。此时相当于deleteOne()
    db.students.remove({name:'liu',true})
    # 删除集合所有数据,性能较差,先匹配在删除
    db.students.remove({})
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2. db.collectionName.deleteOne()

    db.students.deleteOne({name:'liu'})
    
    • 1

    3. db.collectionName.deleteMany()

    db.students.deleteMany({name:'liu'})
    
    • 1

    4. 删除所有数据:db.students.remove({})----性格较差,内部是在一条一条的删除文档。

    # 可直接通过db.students.drop()删除整个集合来提高效率。
    
    • 1

    5.删除集合

    # 清空集合,并把集合也删除
    db.collection.drop()
    
    • 1
    • 2

    6.删除数据库

    db.dropDatabase()
    
    • 1

    7.注意:删除某一个文档的属性,应该用update。 remove以及delete系列删除的是整个文档

    8.当删除的条件为内嵌的属性时:

    db.users.remove({"hobby.movies":'movie3'})
    
    • 1

    9.删除重复

    参考:Mongodb操作(二):批量查重及去重

    # 先查询重复 对应sql 
    select deviceCode,timestamp,count(*) as count from data where deviceCode = '22122121' group by deviceCode,timestamp having count>1;
    # mongodb
    db.data.aggregate([ {$match: {deviceCode: '22122121'}},{$group: { _id : {deviceCode:"$deviceCode",timestamp:"$timestamp" }, count: {$sum: 1}}}, {$match: {count: {$gt: 1}}}], {allowDiskUse: true})
    
    ## 删除
    db.data.aggregate([ {$match: {deviceCode: '22122121'}},{$group: { _id : {deviceCode:"$deviceCode",timestamp:"$timestamp" }, count: {$sum: 1},'dups':{'$addToSet':'$_id'}}}, {$match: {count: {$gt: 1}}}], {allowDiskUse: true}).forEach(function(doc){
    	doc.dups.shift();
    	db.data.remove({_id:{$in:doc.dups}});
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    参数解释

    (1)根据author_name、tid等分组并统计数量, g r o u p 只会返回参与分组的字段,使用 group只会返回参与分组的字段,使用 group只会返回参与分组的字段,使用addToSet在返回结果数组中增加_id字段
    (2)使用 m a t c h 匹配数量大于 1 的数据( 3 ) d o c . d u p s . s h i f t ( ) ; 作用是剔除重复数据其中一 个 i d ,让后面的删除语句不会删除所有数据( 4 )使用 f o r E a c h 循环根 据 i d 删除数据( 5 ) match匹配数量大于1的数据 (3)doc.dups.shift();作用是剔除重复数据其中一个_id,让后面的删除语句不会删除所有数据 (4)使用forEach循环根据_id删除数据 (5) match匹配数量大于1的数据(3doc.dups.shift();作用是剔除重复数据其中一id,让后面的删除语句不会删除所有数据(4)使用forEach循环根id删除数据(5addToSet 操作符只有在值没有存在于数组中时才会向数组中添加一个值。如果值已经存在于数组中,$addToSet返回,不会修改数组。
    (6)allowDiskUse: true
    数据过大会报内存错误:Exceeded memory limit for g r o u p , b u t d i d n ′ t a l l o w e x t e r n a l s o r t . P a s s a l l o w D i s k U s e : t r u e t o o p t i n 可以在后面添加上这个属性就不会了。数据不大的情况下,可以不用试一下注意: f o r E a c h 和 group, but didn't allow external sort. Pass allowDiskUse:true to opt in 可以在后面添加上这个属性就不会了。数据不大的情况下,可以不用试一下 注意:forEach和 group,butdidntallowexternalsort.PassallowDiskUse:truetooptin可以在后面添加上这个属性就不会了。数据不大的情况下,可以不用试一下注意:forEachaddToSet的驼峰写法不能全部写成小写,因为mongodb严格区分大小写。

    文档关系

    一对一

    db.wifeAndHusband.insert([
    	{
    		name:'黄蓉',
    		husband:{
    			name:'郭靖'
    		}
    	},
    	{
    		name:'潘金莲',
    		husband:{
    			name:'武大郎'
    		}
    	}
    ])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    查询db.wifyAndHusband.find()
    在这里插入图片描述

    一对多

    #用户与订单:
    db.users.insert([
    {_id:100,username:'liu1'},
    {_id:101,username:'liu2'}
    ])
    db.orders.insert([
    {list:['apple','banana'],user_id:100},
    {list:['apple','banana2'],user_id:100},
    {list:['apple'],user_id:101}
    ])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    查询liu1的所有订单:
    首先获取liu1的id: var user_id=db.users.findOne({name:‘liu1’})._id;
    根据id从订单集合中查询对应的订单: db.orders.find({user_id:user_id})

    多对多

    #老师与学生
    db.teachers.insert([
        {
            _id:100,
            name:'liu1'
        },
        {
            _id:101,
            name:'liu2'
        },
        {
        	_id:102,
        	name:'liu3'
        }
    ])
    
    db.students.insert([
    	{
    		_id:1000,
    		name:'xiao',
    		tech_ids:[100,101]
    	},
    	{
    		_id:1001,
    		name:'xiao2',
    		tech_ids:[102]
    	}
    ])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    聚合查询

    我们在查询时肯定会用到聚合,在MongoDB中聚合为aggregate,

    聚合函数主要用到$match$group, $avg, $project, $concat
    
    
    • 1
    • 2

    在这里插入图片描述

    演示数据

    在这里插入图片描述

    Aggregate语法

    基本格式:

    db.collection.aggregate(pipeline,options)
    
    • 1
    • pipeline
      一系列数据聚合操作或阶段。在版本2.6中更改:该方法仍然可以将流水线阶段作为单独的参数
      接受,而不是作为数组中的元素;但是,如果不将管道指定为数组,则不能指定options参数。目前所使用的4.0.4版本必须使用数组。
    • options
      可选。aggregate()传递给聚合命令的其他选项。2.6版中的新增功能:仅当将管道指定为数组时
      才可用。

    注意:使用db.collection.aggregate()直接查询会提示错误,但是传一个空数组如db.collection.aggregate([])则不会报错,且会和find一样返回所有文档。

    $match和 $group

    在这里插入图片描述

    相当于sq语句中的where和group by
    {"$match": {"字段": "条件"}}},可以使用任何常用查询操作符$gt,$lt $in# select * from db1.emp where post='公务员'
    db.emp.aggregate([{"$match":{"post":"公务员"}}])
    
    # select* from db1.emp where id > 3 group by post;
    db.emp.aggregate([
    	{"$match":{"_id":{"$gt":3}}},
    	{"$group":{"_id":"$post":'avg.salary':{"$avg":"$salary"}}}
    ])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述

    # select * from db1.emp where id > 3 group by post having avg(salary) > 10000;
    db.emp.aggregate([
    	{"$match":{"_id":{"$gt":3}}},
    	{"$group":{"_id":"$post":'avg.salary':{"$avg":"$salary"}}},
    	{"$match":{"avg.salary":{"$gt":10000}}},
    ])
    
    # "$group":("_id:分组字段,"新的字段名":聚合操作符}}
    
    # 1)、将分组字段传给$group函数的_id字段即可
    	{"$group":{"_id":"$sex"}} # 按照性别分组
    	{"$group":{"_id":"$post"}} # 按照职位分组
    	{"$group":{"_id":{"state":"$state","city":"$city"}}} # 按照多个字段分组,比如按照州市分组
    	
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这里插入图片描述

    取最大值和最小值

    在这里插入图片描述

    取分组里面最大的id和最小的id

    在这里插入图片描述

    求每个岗位的总工资并排序

    在这里插入图片描述

    求每个岗位的人数

    在这里插入图片描述
    数组操作符(重复/不重复)求每个岗位中的所有人名
    在这里插入图片描述

    查询岗位名以及岗位内的员工姓名:select post,group_concat(name) from db1.emp group by post;

    重复的也查出来
    在这里插入图片描述

    查询不重复的,如果有重复的保留一个

    $project

    用于投射,及设定该键值对是否保留。1为保留,0为不保留,可对原有键值对做操作后,增加自定义表达式(查询哪些要显示的列)

    {"$project": {"要保留的字段名":1,"要去掉的字段名":0,"新增的字段名":"表达式"}}
    
    # select name,post,(age+1) as new_age from db1.emp;
    db.emp.aggregate([
    	{
    		$project:{
    			"name":1,
    			"post":1.
    			"new_age":{"$add":["$age",1]}
    		}
    	}
    ])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    $sort 和 $limit 和 $skip

    在这里插入图片描述

    取平均工资最高的两个岗位

    在这里插入图片描述

    去平均工资最高的第二个岗位

    在这里插入图片描述

    $simple

    随机获取3个文档
    在这里插入图片描述

    $concat 和 $substr 和 $toLower 和 $toUpper

    在这里插入图片描述

    截取字符串,不展示_id

    在这里插入图片描述

    拼接

    在这里插入图片描述

    将性别转换为大写

    在这里插入图片描述

    索引

    创建索引

    索引通常能够极大的提供查询的效率,MongoDB使用createIndex()方法来创建索引,其基本语法格式如下所示:

    db.tower_crane_data.createIndex({"deviceCode":1,"timestamp":-1});
    
    • 1

    key:创建的索引字段,1为指定升序创建索引,-1则按照降序来创建索引

    db.user.createIndex({"name":-1})
    # 指定所建立索引的名字
    db.user.createIndex({"name":1},{"name":"nameIndex"})
    
    • 1
    • 2
    • 3

    ensureIndex()接收可选参数,可选参数列表如下:

    查询索引

    db.collection_name.getIndexes()
    
    • 1

    explain输出

    explain 可以为查询提供大量的信息。对于慢查询来说,它是最重要的诊断工具之一。通过查看一个查询的 explain输出,可以了解查询都使用了哪些索引以及是如何使用的。对于任何查询,都可以在末尾添加一个 explain 调用(就像添加sort 或 limit 一样,但是 explain 必须是最后一个调用)。
    重要字段的详细介绍:
    “isMultiKey” : false
    本次查询是否使用了多键索引
    “nReturned” : 8449
    本次查询返回的文档数量。
    “totalDocsExamined” : 8449
    MongoDB 按照索引指针在磁盘上查找实际文档的次数。如果查询中包含的查询条件不是索引的一部分,或者请求的字段没有包含在索引中,MongoDB 就必须查找每个索引项所指向的文档。
    “totalKeysExamined” : 8449
    如果使用了索引,那么这个数字就是查找过的索引条目数量。如果本次查询是一次全表扫描,那么这个数字就表示检查过的文档数量。
    “stage” : “IXSCAN”
    MongoDB 是否可以使用索引完成本次查询。如果不可以,那么会使用 “COLLSCAN” 表示必须执行集合扫描来完成查询。
    “needYield” : 0
    为了让写请求顺利进行,本次查询所让步(暂停)的次数。如果有写操作在等待执行,那么查询将定期释放它们的锁以允许写操作执行。在本次查询中,由于并没有写操作在等待,因此查询永远不会进行让步。
    “executionTimeMillis” : 15
    数据库执行本次查询所花费的毫秒数。这个数字越小越好。“executionTimeMillis” 报告了查询的执行速度,即从服务器接收请求到发出响应的时间。然而,这可能并不总是你希望看到的值。如果 MongoDB 尝试了多个查询计划,那么"executionTimeMillis" 反映的是所有查询计划花费的总运行时间,而不是所选的最优查询计划所花费的时间。
    “indexBounds” : {…}
    这描述了索引是如何被使用的,并给出了索引的遍历范围。

    如果发现 MongoDB 正在使用的索引与自己希望的不一致,则可以用 hint 强制其使用特定的索引。

    注:如果查询没有使用你希望其使用的索引,而你使用了 hint强制进行更改,那么应该在部署之前对这个查询执行 explain。如果强制 MongoDB 在它不知道如何使用索引的查询上使用索引,则可能会导致查询效率比不使用索引时还要低。

    配置修改

    忘记密码

    mongodb忘记密码处理步骤

  • 相关阅读:
    备战数学建模37-遗传算法GA(攻坚战1)
    金仓数据库KingbaseES数据库参考手册(服务器配置参数2. 参数作用域)
    网络应用层之(1)DHCPv6协议
    QGIS 使用矢量数据(shp)批量裁剪栅格数据(tif)
    arm 内核版本编译记录
    使用更灵活、更方便的罗氏线圈
    mysql、oracle、sqlsever使用不同案例
    {“Code“:“InvalidParameterValue.TemplateParameterFormatError“
    导致静脉炎的因素有哪些呢?
    【博学谷学习记录】超强总结,用心分享丨大数据超神之路(五):Hadooop进阶版
  • 原文地址:https://blog.csdn.net/Blueeyedboy521/article/details/127620407