• MongoDB学习笔记(三、MongoDB聚合与更新)


    目录:

    • 聚合
    • 更新
    • 更新选择器
    • ObjectId
    • 更新操作的原子性

    聚合:

    聚合语法:db.collectionName.aggregate(aggregate_operation)

    聚合操作其实就是管道操作,上一次操作的结果集就是下一次管道的输入数据。

    1、$group:分组计算

    • $sum、$avg、$min、$max:获取分组集合中的总和、平均值、最大值、最小值
    • $push:将指定表达式添加到一个数组中
    • $addToSet:将指定表达式添加到集合中(无重复)
    • $first:返回每组第一个文档,如有排序按照排序返回,没有则按照文档的默认顺序
    • $last:同$first,但返回最后一个文档

    示例

    1、统计不同住址的用户人数
    db.users.aggregate({
        '$group':{'_id':'$address', 'number':{'$sum':1}}
    })
    
    2、分别拿到每个住址区域中升高最高的
    db.users.aggregate({
        '$group':{'_id':'$address', 'number':{'$max':'$length'}}
    })
    
    3、分组用户住址,并显示此区域下所有的用户姓名
    db.users.aggregate({
        '$group':{'_id':'$address', 'username':{'$push':'$username'}}
    })
    
    4、分组用户住址,并显示此区域下最后一名用户的姓名
    db.users.aggregate({
        '$group':{'_id':'$address', 'lastUsername':{'$last':'$username'}}
    })

    2、$project:输出文档中指定的字段。

    示例:

    1、获取每个用户的年龄及身高
    db.users.aggregate({
        '$project':{'age':1, 'length':1}
    })

    3、$match:过滤数据,使用mongoDB标准的查询操作($eq、$ne等等)。

    示例:

    1、获取升高大于1.8的用户姓名及身高
    db.users.aggregate( {
    '$match':{'length':{'$gt':1.8}}}, {'$project':{'username':1, 'length':1}} )

    4、$limit:限制文档返回数量;$skip:跳过指定数量的文档、$sort:排序(1=升序,-1=降序)。

    示例:

    1、获取身高第二和第三高的用户姓名
    db.users.aggregate(
        {'$sort':{'length':-1}},
        {'$skip':1},
        {'$limit':2},
        {'$project':{'username':1}}
    )

    5、$unwind:将文档中某一个数组拆分成多条。

    示例:

    1、获取被评论次数最多的电影
    db.users.aggregate(
        {'$unwind':'$comments'},
        {'$group':{'_id':'$comments.movies', 'count':{'$sum':1}}},
        {'$sort':{'count':-1}},
        {'$limit':1},
        {'$project':{'_id':1}}
    )

    spring data mongoDB写法见:https://github.com/mrjdrs/mongodb-demo/tree/master/mongo-selector

    更新:

    在mongo中更新分为两种:

    1、替换更新:使用新文档替代旧文档。

    2、操作符更新:在一个或多个文档上修改。

    更新语法

    db.collectionName.update(
        <query>,
        <update>,
        {upsert:<boolean>, multi:<boolean>, wirteConcern:<document>}
    )

    参数说明

    1、query:更新的查询条件

    2、update:更新操作符的选择

    3、upsert:若不存在更新的数据,是否插入一条新的数据;true=插入,false=不插入(默认)。

    4、multi:是否更新多条,true=更新找到的多条数据,false=仅更新找到的第一条(默认)。

    5、writeConcern:写入数据的安全配置。

    更新选择器:

    示例

    1、将java编程思想这本书籍价格加10
    db.product.update(
        {'name':'java编程思想'},
        {'$inc':{'price':10}}
    )
    
    2、更新java编程思想这本书名为java编程思想第四版
    db.product.update(
        {'name':'java编程思想'},
        {'$set':{'name':'java编程思想第四版'}}
    )
    
    3、将姓名为路飞,评论电影为战狼的那条数据修改评论为战狼电影的评论
    // 注意$操作符一次只能修改一条数据
    db.users.update(
        {'username':'路飞', 'comments.movies':'战狼'},
        {'$set':{'comments.$.content':'战狼电影的评论'}}
    )
    
    4、为书籍java编程思想第四版添加两个标签值
    db.product.update(
       {'name':'java编程思想第四版'},
       {'$push':{'tags':{'$each':['标签1', '标签2']}}}
    )

    spring data mongoDB写法见:https://github.com/mrjdrs/mongodb-demo/tree/master/mongo-selector

    ObjectId:

    我们知道在mongo中insert操作是没有返回值的,但有些业务场景又需要拿到insert后的id,那我们改怎么办呢?

    我们发现mongo的update操作有返回值,所以可以用update代替insert来获取ObjectId,以完成上述的业务场景。

    db.users.update(
        {'':''},
        {'username':'zd'},
        {'upsert':true}
    )

    更新操作的原子性:

    mongo的所有更新都是原子的,所有的写操作都有锁;2.2版本之前是实例级别,2.2之后是数据库级别,3.0+为文档级别。

    原子性更新的语法

    db.collectionName.findAndModify({
        query:{},
        updae:{},
        remove:true|false,
        new:true|false,
        sort:{},
        fields:{},
        upsert:true|false
    })

    参数解释

    1、query:查询选择器

    2、update:要更新的值,不能与remote同时出现

    3、remove:删除符合query条件的文档,不能与update同时出现

    4、new:true=返回更新后的文档,false=返回更新前的文档;默认false

    5、sort:排序条件

    6、fields:投影操作,与find操作的第二个参数一致

    7、upsert:与update的upsert参数一致,但它不仅会插入update的内容,还会插入query的内容

  • 相关阅读:
    变量提升
    前端UI框架和JS类库
    ES6---Map数据结构
    ES6---Set数据结构
    Array.from//Array.of的用法
    闭包的理解和应用场景
    vue-router 的用法
    原型链和作用域链的理解
    WordPress更换了域名 主页、文章、图片路径错误 解决办法
    wordpress 安装新的主题后启动后报错
  • 原文地址:https://www.cnblogs.com/bzfsdr/p/11965594.html
Copyright © 2020-2023  润新知