• mongodb基本操作命令



    前言:本篇默认你是对nongodb的基础概念有了了解,操作是非常基础的。但是与关系型数据库的类比默认你已经是了解的。

    1.mongodb安装

    这里为了快速使用mongodb,我使用了docker安装(如果想了解linux上面的安装可以参考我的另一篇文章《mongdb下载、安装、启动》)。

    1.1 docker安装启动mongodb

    #拉取mongo镜像
    docker pull mongo:4.4.10
    #运行mongo镜像
    docker run --name mongo-server -p 29017:27017 \
    -e MONGO_INITDB_ROOT_USERNAME=root\
    -e MONGO_INITDB_ROOT_PASSWORD=root\
    -d mongo:4.4.10 --wiredTigerCacheSizeGB 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    默认情况下,Mongo会将wiredTigerCacheSizeGB设置为与主机总内存成比例的值,而不考虑你可能对容器施加的内存限制。
    MONGO_INITDB_ROOT_USERNAME和MONGO_INITDB_ROOT_PASSWORD都存在就会启用身份认证(mongod --auth)

    #进入容器
    docker exec -it mongo-server  bash
    #进入Mongo shell
    mongo -u root-p root
    
    • 1
    • 2
    • 3
    • 4

    2.mongo shell常用命令

    命令说明
    show dbs/show databases显示数据库列表
    use 数据库名切换数据库,如果不存在创建数据库
    db.dropDatabase()删除数据库
    show collections/show tables显示当前数据库的集合列表
    db.createCollection(“集合名”)创建集合
    db.集合名.stats()查看集合详情
    db.集合名.drop()删除集合
    show users显示当前数据库的用户列表
    show roles显示当前数据库的角色列表
    db.createUser({user:“用户名”,pwd:“用户密码”,roles:[“角色”]})创建管理员
    db.dropUser(“用户名”)删除用户
    show profile显示近发生的操作
    load(“xxx.js”)执行一个JavaScript脚本文件
    exit /quit()退出当前shell
    help查看mongodb支持哪些命令
    db.help()查询当前数据库支持的方法
    db.集合名.help()显示集合的帮助信息
    db.version()查看数据库版本

    2.1 插入文档

    2.1.1 插入单个文档

    • insertOne: 支持writeConcern
    db.collection.insertOne(
       <document>,
       {
          writeConcern: val
       }
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    writeConcern 决定一个写操作落到多少个节点上才算成功。writeConcern 的取值val包括:
    0: 发起写操作,不关心是否成功;
    1: 集群最大数据节点数:写操作需要被复制到指定节点数才算成功;
    majority: 写操作需要被复制到大多数节点上才算成功

    db.emps.insertOne({x:22,y:12},{writeConcern:0})
    
    • 1

    在这里插入图片描述

    • insert: 若插入的数据主键已经存在,则会抛 DuplicateKeyException 异常,提示主键重复,不保存当前数据
    db.emps.insert({x:11,y:22})
    
    • 1

    在这里插入图片描述

    • save: 如果 _id 主键存在则更新数据,如果不存在就插入数据
    db.emps.save({_id:ObjectId("65674b35fc0731432f162147"),x:12,y:21})
    
    • 1

    在这里插入图片描述

    2.1.2 插入多个文档

    • insertMany:向指定集合中插入多条文档数据
    db.collection.insertMany(
       [ <document 1> , <document 2>, ... ],
       {
          writeConcern: <document>,
          ordered: <boolean>      
       }
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    writeConcern:写入策略,默认为 1,即要求确认写操作,0 是不要求。
    ordered:指定是否按顺序写入,默认 true,按顺序写入。

    db.emps.insertMany([{x:23,y:23},{x:33,y:33}],{writeConcern:0,ordered:true})
    
    • 1

    在这里插入图片描述

    2.1.3 用脚本批量插入

    # 退出mongo shell
    exit
    # docker容器内部也是一个小型的linux环境
    # 更新依赖
    apt-get update  
    # 安装vim命令
    apt-get install vim
    
    
    cd /data/db/
    vim books.js
    # 以下内容粘贴在books.js中
    var tags = ["nosql","mongodb","document","developer","popular"];
    var types = ["technology","sociality","travel","novel","literature"];
    var books=[];
    for(var i=0;i<50;i++){
        var typeIdx = Math.floor(Math.random()*types.length);
        var tagIdx = Math.floor(Math.random()*tags.length);
        var favCount = Math.floor(Math.random()*100);
        var book = {
            title: "book-"+i,
            type: types[typeIdx],
            tag: tags[tagIdx],
            favCount: favCount,
            author: "xxx"+i
        };
        books.push(book)
    }
    db.books.insertMany(books);
    
    • 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
    # 进入mongo shell
    mongo -u root -p root
    # 加载js文件
    load("books.js")
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    2.2 查询文档

    2.2.1 条件查询

    db.collection.find(query, projection)
    
    • 1

    query :可选,查询的条件
    projection :可选,使用投影操作符指定返回的键。默认省略:查询时返回文档中所有键值。_id为1的时候,其他字段必须是1;_id是0的时候,其他字段可以是0;如果没有_id字段约束,多个其他字段必须同为0或同为1。

    # 只指定查询条件 tag=nosql
    db.books.find({tag:"nosql"})
    # 指定查询条件 且 指定title,author不展示
    db.books.find({tag:"nosql"},{title:0,author:0})
    # 指定查询条件 且 只展示title,author
    db.books.find({tag:"nosql"},{title:1,author:1})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    # 指定查询条件 且 只展示title,author,隐藏_id
    db.books.find({tag:"mongodb"},{type:1,author:1,_id:0})
    # 同时指定01仍然会报错
    db.books.find({tag:"mongodb"},{type:0,author:1,_id:0})
    # 指定查询条件 且 指定title,author不展示,隐藏_id
    db.books.find({tag:"mongodb"},{type:0,author:0,_id:0})
    # 指定查询条件 且 指定title,author不展示,不隐藏_id
    db.books.find({tag:"mongodb"},{type:0,author:0,_id:1})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述
    查询条件对照表

    SQLMQL
    a=1{a:1}
    a<>1{a:{$ne:1}}
    a>1{a:{$gt:1}}
    a>=1{a:{$gte:1}}
    a<1{a:{$lt:1}}
    a<=1{a:{$lte:1}}

    查询逻辑对照表

    SQLMQL
    a=1and b=1{a:1,b:1}或{$and:[{a:1},{b:1}]}
    a=1or b=1{$or:[{a:1},{b:1}]}
    a is null{a: {$exists: false}}
    a in (1, 2, 3){a:{$gte:1}}
    a<1{a:{$in:[1,2,3]}}
    # 查询条件 type=travel 且 favCount > 40
    db.books.find({type:"travel",favCount:{$gt:40}})
    # 查询条件 type=travel 且 favCount > 40
    db.books.find({$and:[{type:"travel"},{favCount:{$gt:40}}]})
    # 查询条件 type=travel 或者 favCount > 40
    db.books.find({$or:[{type:"travel"},{favCount:{$gt:40}}]})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    2.2.2 排序查询

    db.books.find({type:"travel"}).sort({favCount:1})
    db.books.find({type:"travel"}).sort({favCount:-1})
    
    • 1
    • 2

    1 为升序排列,而 -1 是用于降序排列

    在这里插入图片描述

    2.2.3 分页查询

    skip用于指定跳过记录数,limit则用于限定返回结果数量。可以在执行find命令的同时指定skip、limit参数,以此实现分页的功能。比如,假定每页大小为8条,查询第3页的book文档(查询第三页即跳过2*8=16条,限定展示8条):

    db.books.find().skip(16).limit(8)
    
    • 1

    在这里插入图片描述
    处理分页问题 – 巧分页
    数据量大的时候,应该避免使用skip/limit形式的分页。
    替代方案:使用查询条件+唯一排序条件;
    例如:

    # 第一页数据根据id排序,限定10条
    db.books.find().sort({_id:1}).limit(10)
    # 第二页数据根据id排序,且_id>第一页最后一个_id,限定10条
    db.books.find({_id:{$gt:ObjectId("65673c1afc0731432f16211c")}}).sort({_id:1}).limit(10)
    # 第三页数据根据id排序,且_id>第二页最后一个_id,限定10条
    db.books.find({_id:{$gt:ObjectId("65673c1afc0731432f162126")}}).sort({_id:1}).limit(10)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    处理分页问题 – 避免使用 count
    尽可能不要计算总页数,特别是数据量大和查询条件不能完整命中索引时。
    考虑以下场景:假设集合总共有 1000w 条数据,在没有索引的情况下考虑以下查询:

    db.coll.find({x: 100}).limit(50);
    db.coll.count({x: 100}); 
    
    • 1
    • 2

    前者只需要遍历前 n 条,直到找到 50 条 x=100 的文档即可结束; 后者需要遍历完 1000w 条找到所有符合要求的文档才能得到结果。 为了计算总页数而进行的 count() 往往是拖慢页面整体加载速度的原因

    2.2.4 正则表达式匹配查询

    //使用正则表达式查找type包含 so 字符串的book
    db.books.find({type:{$regex:"so"}})
    //或者
    db.books.find({type:/no/})
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    2.3 更新文档

    2.3.1 条件更新

    db.collection.update(query,update,options)
    
    • 1
    • query:更新的查询条件;
    • update:更新的动作及新的内容;
    • options:更新的选项
      • upsert: 可选,如果不存在update的记录,是否插入新的记录。默认false,不插入
      • multi: 可选,是否按条件查询出的多条记录全部更新。 默认false,只更新找到的第一条记录
      • writeConcern :可选,决定一个写操作落到多少个节点上才算成功。

    更新操作符

    序号操作符格式描述
    1$set{$set:{filed:value}}指定键更新,若不存在在创建
    2$unset{$unset:{filed:value}}删除一个键
    3$inc{$inc:{filed:value}}对数值类型进行增减
    4$rename{$rename:{old_filed_name:new_filed_name}}修改字段名称
    5$push{$push:{filed:value}}追加值到数组中,不存在则会进行初始化
    6$push + $each{push:{filed:{$each:value_array}}}追加多个值到一个数组字段
    7$pull{$pull:{filed:value}}从数组中删除指定元素
    8$addToSet{$addToSet:{filed:value}}向一个数组中添加值,同时避免重复值的出现
    9$pop{$pop:{filed:1}}删除数组第一个或者最后一个元素

    1.指定条件_id,更新title的值

    db.books.update({_id:ObjectId("65673c1afc0731432f162113")},{$set:{title:"book-000"}})
    
    • 1

    在这里插入图片描述
    2.指定条件_id,删除title的值

    db.books.update({_id:ObjectId("65673c1afc0731432f162113")},{$unset:{title:"book-000"}})
    
    • 1

    在这里插入图片描述
    3.指定数值类型增减

    # 对指定条件的数据 favCount+1
    db.books.update({_id:ObjectId("65673c1afc0731432f162113")},{$inc:{favCount:1}})
    # 对指定条件的数据 favCount+2
    db.books.update({_id:ObjectId("65673c1afc0731432f162113")},{$inc:{favCount:2}})
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述
    4.修改字段名称

    # 指定_id,修改这条数据的tag-0名称为tag
    db.books.update({_id:ObjectId("65673c1afc0731432f162126")},{$rename:{"tag-0":"tag"}})
    
    • 1
    • 2

    在这里插入图片描述
    5.追加值到数组中

    db.books.update({_id:ObjectId("65673c1afc0731432f162113")},{$push:{title:"book-001"}})
    
    • 1

    在这里插入图片描述
    6.追加多个值到一个数组字段中

    # 将多个值分别插入title
    db.books.update({_id:ObjectId("65673c1afc0731432f162113")},{$push:{title:{$each:["book-002","book-003","book-004"]}}})
    
    • 1
    • 2

    在这里插入图片描述

    7.从数组中删除指定元素

    db.books.update({_id:ObjectId("65673c1afc0731432f162113")},{$pull:{title:"book-001"}})
    
    • 1

    在这里插入图片描述
    8.向一个数组中添加值,同时避免重复值的出现

    在这里插入图片描述
    9.删除数组第一个或者最后一个元素

    # 删除数组最后一个元素
    db.books.update({_id:ObjectId("65673c1afc0731432f162113")},{$pop:{title:1}})
    # 删除数组第一个元素
    db.books.update({_id:ObjectId("65673c1afc0731432f162113")},{$pop:{title:-1}})
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    2.3.2 更新多条

    db.books.update({type:"novel"},{$set:{publishedDate:new Date()}},{"multi":true})
    
    • 1

    在这里插入图片描述
    update命令的选项配置较多,为了简化使用还可以使用一些快捷命令:

    • updateOne:更新单个文档。
    • updateMany:更新多个文档。
    • replaceOne:替换单个文档。

    使用upsert命令

    db.books.update(
        {title:"my book"},
        {$set:{tags:["nosql","mongodb"],type:"none",author:"hotdog"}},
        {upsert:true}
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    nMatched、nModified都为0,表示没有文档被匹配及更新,nUpserted=1提示执行了upsert动作

    实现replace语义
    update命令中的更新描述(update)通常由操作符描述,如果更新描述中不包含任何操作符,那么MongoDB会实现文档的replace语义

    db.books.update(
        {title:"my book"},
        {justTitle:"my first book"}
    )   
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    2.4 删除文档

    2.4.1 使用 remove 删除文档

    • remove 命令需要配合查询条件使用;
    • 匹配查询条件的文档会被删除;
    • 指定一个空文档条件会删除所有文档;
    db.emps.remove({x:1})// 删除x等于1的记录,可以删除多条
    db.emps.remove({x:2},true)// 删除x等于2的记录,只删除一条
    db.emps.remove({x:{$lt:25}})   // 删除x小于25的记录
    db.user.remove( { } ) // 删除所有记录
    db.user.remove() //报错
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述
    在这里插入图片描述

    2.4.2 使用 delete 删除文档

    官方推荐使用 deleteOne() 和 deleteMany() 方法删除文档,语法格式如下:

    db.books.deleteMany ({})  //删除集合下全部文档
    db.books.deleteMany ({ type:"novel" })  //删除 type等于 novel 的全部文档
    db.books.deleteOne ({ type:"novel" })  //删除 type等于novel 的一个文档
    
    • 1
    • 2
    • 3

    注意: remove、deleteMany等命令需要对查询范围内的文档逐个删除,如果希望删除整个集合,则使用drop命令会更加高效

    2.4.3 返回被删除文档

    remove、deleteOne等命令在删除文档后只会返回确认性的信息,如果希望获得被删除的文档,则可以使用findOneAndDelete命令

    db.books.findOneAndDelete({type:"novel"})
    
    • 1

    在这里插入图片描述

  • 相关阅读:
    【Kubernetes】浅聊Kubernetes中的容器和镜像
    Wespeaker框架数据集准备(1)
    详解 NFT 借贷资金池清算机制:如何避免 BendDAO 式流动性危机?
    Excel新手教程
    讲解 CSS 过渡和动画 — transition/animation (很全面)
    OpenGL学习——16.多光源
    互联网Java工程师面试题·Dubbo篇·第一弹
    Node.js精进(2)——异步编程
    Java EE——线程池
    Day53【动态规划】1143.最长公共子序列、1035.不相交的线、53.最大子序和
  • 原文地址:https://blog.csdn.net/qq_45003354/article/details/134700441