美文网首页
2. Mongo基本命令操作

2. Mongo基本命令操作

作者: DDLH | 来源:发表于2019-11-08 13:50 被阅读0次

    先来一个常用的赋值和输出命令,熟悉一下。(操作前你需要打开并链接到服务器)在命令行中输入以下代码。

    var x='Hello World'
    print(x)
    

    需要注意的是这里的输出不再使用console.log(‘xxx’),而是使用print(‘xxx’),这个稍有区别。

    还可以定义函数:

    function fn(){
        return '我是定义的函数。。。。';
    }
    print(fn())
    

    基础Shell命令:

    • show dbs :显示已有数据库,如果你刚安装好,会默认有local、admin、config,这是MongoDB的默认数据库,我们在新建库时是不允许起这些名称的。
    • use test: 进入数据,也可以理解成为使用数据库。成功会显示:switched to db test。
    • show collections: 显示数据库中的集合(关系型中叫表)。
    • db:显示当前位置,也就是你当前使用的数据库名称,这个命令算是最常用的,因为你在作任何操作的时候都要先查看一下自己所在的库,以免造成操作错误。

    输出结果如下(test数据库为自己创建的一个数据库,里面有cus和user两个表):

    > show dbs
    admin   0.000GB
    config  0.000GB
    db      0.000GB
    local   0.000GB
    test    0.000GB
    > use test
    switched to db test
    > show collections
    cus
    user
    > db
    test
    
    

    数据操作基础命令

    • use db(建立数据库):use不仅可以进入一个数据库,如果你敲入的库不存在,它还可以帮你建立一个库。但是在没有集合前,它还是默认为空。
    • db.集合.insert( ):新建数据集合和插入文件(数据),当集合没有时,这时候就可以新建一个集合,并向里边插入数据。Demo:db.user.insert({"name":"ddlh"})
    • db.集合.find( ):查询所有数据,这条命令会列出集合下的所有数据,可以看到MongoDB是自动给我们加入了索引值的。Demo:db.user.find()
    • db.集合.findOne( ):查询第一个文件数据,这里需要注意的,所有MongoDB的组合单词都使用首字母小写的驼峰式写法。Demo:db.user.findOne()
    • db.集合.update({查询},{修改}):修改文件数据,第一个是查询条件,第二个是要修改成的值。这里注意的是可以多加文件数据项的,比如下面的例子。
      db.user.update({"name":"ddlh"},{"name":"duan","age":"18"})
    • db.集合.remove(条件):删除文件数据,注意的是要跟一个条件。
      db.user.remove({"name":"李四"})
    • db.集合.drop( ):删除整个集合,这个在实际工作中一定要谨慎使用,如果是程序,一定要二次确认。
      db.user.drop()
    • db.dropDatabase( ):删除整个数据库,在删除库时,一定要先进入数据库,然后再删除。实际工作中这个基本不用,实际工作可定需要保留数据和痕迹的。
    > use user
    switched to db user
    >
    > show dbs
    admin   0.000GB
    config  0.000GB
    db      0.000GB
    local   0.000GB
    test    0.000GB
    >
    > db.user.insert({"name":"ddlh"})
    WriteResult({ "nInserted" : 1 })
    >
    > db.user.find()
    { "_id" : ObjectId("5d9c5d0b5eda5a6fd0f30d71"), "name" : "ddlh" }
    >
    > db.user.insert({"name":"张三"}))
    WriteResult({ "nInserted" : 1 })
    >
    > db.user.find()
    { "_id" : ObjectId("5d9c5d0b5eda5a6fd0f30d71"), "name" : "ddlh" }
    { "_id" : ObjectId("5d9c5d565eda5a6fd0f30d72"), "name" : "张三" }
    >
    > db.user.insert({"name":"李四"})
    WriteResult({ "nInserted" : 1 })
    >
    > db.user.find()
    { "_id" : ObjectId("5d9c5d0b5eda5a6fd0f30d71"), "name" : "ddlh" }
    { "_id" : ObjectId("5d9c5d565eda5a6fd0f30d72"), "name" : "张三" }
    { "_id" : ObjectId("5d9c5d5e5eda5a6fd0f30d73"), "name" : "李四" }
    >
    > db.user.findOne()
    { "_id" : ObjectId("5d9c5d0b5eda5a6fd0f30d71"), "name" : "ddlh" }
    >
    >
    > db.user.update({"name":"ddlh"},{"name":"duan","age":"18"})
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    >
    >
    > db.user.find()
    { "_id" : ObjectId("5d9c5d0b5eda5a6fd0f30d71"), "name" : "duan", "age" : "18" }
    { "_id" : ObjectId("5d9c5d565eda5a6fd0f30d72"), "name" : "张三" }
    { "_id" : ObjectId("5d9c5d5e5eda5a6fd0f30d73"), "name" : "李四" }
    >
    >
    > db.user.remove({"name":"李四"})
    WriteResult({ "nRemoved" : 1 })
    >
    > db.user.find()
    { "_id" : ObjectId("5d9c5d0b5eda5a6fd0f30d71"), "name" : "duan", "age" : "18" }
    { "_id" : ObjectId("5d9c5d565eda5a6fd0f30d72"), "name" : "张三" }
    >
    >
    > db.user.drop()
    true
    >
    

    用js文件写mongo命令

    在命令行中写mongo的命令(shell)实在是太麻烦了。尝试用JS文件来写shell命令和执行。在JS里写mongo的Shell命令大部分是相同的,只有小部分不一样。

    在D:\code\mongoShell文件夹在创建一个 goTask.js 文件。使用vscode进行编辑,内容如下:

    var userName="ddlh";    //声明一个登录名             
    var timeStamp=Date.parse(new Date());     //声明登录时的时间戳  
    var jsonDdatabase={"loginUnser":userName,"loginTime":timeStamp}; //组成JSON字符串
    var db = connect('log');   //链接数据库
    db.login.insert(jsonDdatabase);  //插入数据
     
    print('[demo]log  print success');  //没有错误显示成功D
    

    执行mongo goTask.js输出结果如下:

    D:\code\mongoShell>mongo goTask.js
    MongoDB shell version v4.2.0
    connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
    Implicit session: session { "id" : UUID("dc243992-c875-4c98-b7c1-899c4c10b107") }
    MongoDB server version: 4.2.0
    connecting to: mongodb://127.0.0.1:27017/log
    Implicit session: session { "id" : UUID("d9f0a88c-3506-43b1-87e9-f0c7936f91ab") }
    MongoDB server version: 4.2.0
    [demo]log  print success
    

    大部分语句和在命令行中写法一样,需要注意的是,连接数据库时,使用var db = connect('log');

    数据的批量插入

    普通批量插入方法:

    批量数据插入是以数组的方式进行的,我们先在命令行中敲入下面的代码,我们可以看到数据顺利插入了。
    db.test.insert([ {"_id":1}, {"_id":2}, {"_id":3} ])

    > db.test.insert([ {"_id":1}, {"_id":2}, {"_id":3} ])
    BulkWriteResult({
            "writeErrors" : [ ],
            "writeConcernErrors" : [ ],
            "nInserted" : 3,
            "nUpserted" : 0,
            "nMatched" : 0,
            "nModified" : 0,
            "nRemoved" : 0,
            "upserted" : [ ]
    })
    > db.test.find()
    { "_id" : 1 }
    { "_id" : 2 }
    { "_id" : 3 }
    >
    

    批量插入性能测试:

    先写一个for循环插入方法:

    var startTime = (new Date()).getTime(); //得到开始时间
    var  db = connect('log');  //链接数据库
    //开始循环
    for(let i=0;i<1000;i++){
        db.test.insert({num:i});
    }
     
    var runTime = (new Date()).getTime()-startTime;//计算时间差
    print ('This run this is:'+runTime+'ms');//打印出来
    

    我测试的时间是1191ms,这个速度虽然和电脑性能有关,但还是不太理想,1000条数据用了一秒多时间。

    批量一次性插入:

    var startTime = (new Date()).getTime();
    var  db = connect('log');
     
     
    var tempArray = []              //声明一个数组
    for(let i=0;i<1000;i++){        //循环向数组中放入值
        tempArray.push({num:i});
    }
    db.test.insert(tempArray)       //批量一次插入
     
    var runTime = (new Date()).getTime()-startTime;
    print ('This run this is:'+runTime+'ms');
    

    这次用了47ms,性能远远超过循环插入。

    总结:在工作中一定要照顾数据库性能,这也是你水平的提现,一个技术会了很简单,但是要作精通不那么简单。在工作中如果在循环插入和批量插入举起不定,那就选批量插入吧,它会给我们更优的性能体验。

    数据修改

    场景1: 只修改某条数据中的一项,(比如修改某一个人的年龄)

    先模拟一个研发部成员的数据

    var workmate1={
      name:'炳哥',
      age:18,
      sex:1,
      job:'前端',
      skill:{
          skillOne:'HTML+CSS',
          SkillTwo:'JavaScript',
          SkillThree:'PHP'
      },
      regeditTime:new Date()
    }
    
    var workmate2={
      name:'军哥',
      age:18,
      sex:1,
      job:'JAVA后端',
      skill:{
          skillOne:'HTML+CSS',
          SkillTwo:'J2EE',
          SkillThree:'PPT'
      },
      regeditTime:new Date()
    }
    
    var workmate3={
      name:'静静',
      age:20,
      sex:0,
      job:'UI设计',
      skill:{
          skillOne:'PhotoShop',
          SkillTwo:'UI',
          SkillThree:'Word+Excel+PPT'
      },
      regeditTime:new Date()
    }
    
    var db=connect('company')
    var workmateArray=[workmate1,workmate2,workmate3]
    db.workmate.insert(workmateArray)
    
    print('[SUCCESS]: The data was inserted successfully.');
    

    上面的代码,我们以文件的形式向数据库中插入了3条数据。
    这时候我们需要把UI的年龄也改成18岁,需要修改这条数据我们可能会这样写。

    // 修改数据  错误示例 会导致这条数据只有一个age
    // db.workmate.update({name:'静静'},{age: 18})
    

    正确的方法
    可以声明一个变量,然后把要改变数据的全部信息放入变量,最后执行修改操作。:

    // 修改数据 正确方法
    var workmate3={
      name:'静静',
      age:18,
      sex:0,
      job:'UI设计',
      skill:{
          skillOne:'PhotoShop',
          SkillTwo:'UI',
          SkillThree:'Word+Excel+PPT'
      },
      regeditTime:new Date()
    }
    db.workmate.update({name:'静静'},workmate3)
    

    注意:这时候静静这个用户已经不在数据库中了,需要重新载入数据再进行修改。

    进阶 update修改器:

    上面方法实现了数据修改正常,但是你会发现写起来非常麻烦,而且特别容易写错。为此我们要学习新知识update修改器,来解决这个问题。它可以帮助我们快速和简单的修改数据,让我们的操作更简单方便。

    • $set修改器

    用来修改一个指定的键值(key),这时候我们要修改某一个就非常方便了,只要一句话就可以搞定。
    db.workmate.update({"name":"静静"},{"$set":{age:21}})

    修改嵌套内容, 如果要修改skill.skillThree的值,可以以属性的形式进行修改:
    db.workmate.update({"name":"静静"},{"$set":{"skill.skillThree":'word'}})

    修改好后,我们可以用db.workmate.find()来进行查看,你会发现数据已经被修改。

    • $unset用于将key删除

    它的作用其实就是删除一个key值和键。一般女孩子都是不希望看到自己的年龄的,所以要求我们把年龄删除。这时候我们就可以使用$unset的形式。

    db.workmate.update({"name":"静静"},{$unset:{"age":''}})

    当你删除后,想加回来可以直接用set进行添加。

    • $inc对数字进行计算

    它是对value值的修改,但是修改的必须是数字,字符串是不起效果的。我们现在要对静静的年龄减去2岁,就可以直接用$inc来操作。

    db.workmate.update({"name":"静静"},{$inc:{"age":-2}})

    • multi选项

    现在领导说了,你要把每个人的爱好也加入进来,但是如果你直接写会只加一个,比如下面这种形式。db.workmate.update({},{$set:{interset:[]}})

    这时候你用db.workmate.find()查找,你会发现只改变了第一个数据,其他两条没有改变。这时候我们想改变就要用到multi选项。

    db.workmate.update({},{$set:{interset:[]}},{multi:true})

    这时候每个数据都发生了改变,multi是有ture和false两个值,true代表全部修改,false代表只修改一个(默认值)

    • upsert选项

    upsert是在找不到值的情况下,直接插入这条数据。比如我们这时候又来了一个新同事xiaoWang,我们这时候修改他的信息,age设置成20岁,但集合中并没有这条数据。这时候可以使用upsert选项直接添加。

    db.workmate.update({name:'xiaoWang'},{$set:{age:20}},{upsert:true})

    upsert也有两个值:true代表没有就添加,false代表没有不添加(默认值)。

    再次进阶 update数组修改器

    修改对象形式的数据

    • $push追加数组/内嵌文档值

    $push的功能是追加数组中的值,但我们也经常用它操作内嵌稳文档,就是{}对象型的值。先看一个追加数组值的方式,比如我们要给小王加上一个爱好(interset)为画画(draw):

    db.workmate.update({name:'xiaoWang'},{$push:{interest:'draw'}})
    
    • $each 批量追加

    它可以传入一个数组,一次增加多个值进去,相当于批量操作,性能同样比循环操作要好很多,这个是需要我们注意的,工作中也要先组合成数组,然后用批量的形式进行操作。

    例子:我们现在要给xiaoWang,一次加入三个爱好,唱歌(Sing),跳舞(Dance),编码(Code)。

    var newInterset=["Sing","Dance","Code"];
    db.workmate.update({name:"xiaoWang"},{$addToSet:{interest:{$each:newInterset}}})
    
    
    • $pop 删除数组值

    $pop只删除一次,并不是删除所有数组中的值。而且它有两个选项,一个是1和-1。

    1:从数组末端进行删除
    -1:从数组开端进行删除

    例子:现在要删除xiaoWang的编码爱好(code)。

    db.workmate.update({name:'xiaoWang'},{$pop:{interest:1}})
    
    • 数组定位修改

    有时候只知道修改数组的第几位,但并不知道是什么,这时候我们可以使用interest.int 的形式。

    例子,比如我们现在要修改xiaoWang的第三个兴趣为编码(Code),注意这里的计数是从0开始的。

    db.workmate.update({name:'xiaoWang'},{$set:{"interest.2":"Code"}})

    状态返回与安全

    在实际工作中,我们用db.collections.update的时候不多,在修改时我们都会用findAndModify,它可以给我们返回来一些必要的参数,让我们对修改多了很多控制力,控制力的加强也就是对安全的强化能力加强了。

    应答式写入: db.runCommand();

    它是数据库运行命令的执行器,执行命令首选就要使用它,因为它在Shell和驱动程序间提供了一致的接口。(几乎操作数据库的所有操作,都可以使用runCommand来执行)现在我们试着用runCommand来修改数据库,看看结果和直接用db.collections.update有什么不同。

    db.workmate.update({sex:1},{$set:{money:1000}},false,true)
    var resultMessage=db.runCommand({getLastError:1})
    printjson(resultMessage);
    

    上边的代码,我们修改了所有男士的数据,每个人增加了1000元钱(money),然后用db.runCommand()执行,可以看到执行结果在控制台返回了。

    {
            "connectionId" : 699,
            "updatedExisting" : true,
            "n" : 2,
            "syncMillis" : 0,
            "writtenTo" : null,
            "err" : null,
            "ok" : 1
    }
    
    • false:第一句末尾的false是upsert的简写,代表没有此条数据时不增加;
    • true:true是multi的简写,代表修改所有,这两个我们在前边课程已经学过。
    • getLastError:1 :表示返回功能错误,这里的参数很多,如果有兴趣请自行查找学习,这里不作过多介绍。
    • printjson:表示以json对象的格式输出到控制台。
    • db.listCommands( ):查看所有的Commad命令

    比如我们要查看是否和数据库链接成功了,就可以使用Command命令 db.runCommand({ping:1})
    返回ok:1就代表链接正常。

    findAndModify:

    从名字上就可以看出,findAndModify是查找并修改的意思。配置它可以在修改后给我们返回修改的结果。我们先看下面的代码:

    var myModify={
        findAndModify:"workmate",
        query:{name:'静静'},
        update:{$set:{age:16}},
        new:true    //更新完成,需要查看结果,如果为false不进行查看结果
    }
    var ResultMessage=db.runCommand(myModify);
     
    printjson(ResultMessage)
    
    

    输出结果:

    {
            "lastErrorObject" : {
                    "n" : 1,
                    "updatedExisting" : true
            },
            "value" : {
                    "_id" : ObjectId("5d9c78eab47ac78ecc6d3c74"),
                    "name" : "静静",
                    "sex" : 0,
                    "job" : "UI设计",
                    "skill" : {
                            "skillOne" : "PhotoShop",
                            "SkillTwo" : "UI",
                            "SkillThree" : "Word+Excel+PPT",
                            "skillThree" : "word1"
                    },
                    "regeditTime" : ISODate("2019-10-08T11:54:18.263Z"),
                    "age" : 16,
                    "interset" : [ ]
            },
            "ok" : 1
    }
    

    findAndModify属性值:

    • query:需要查询的条件/文档
    • sort: 进行排序
    • remove:[boolean]是否删除查找到的文档,值填写true,可以删除。
    • new:[boolean]返回更新前的文档还是更新后的文档。
    • fields:需要返回的字段
    • upsert:没有这个值是否增加。

    findAndModify的性能是没有直接使用db.collections.update的性能好,但是在实际工作中都是使用它,毕竟要商用的程序安全性还是比较重要的。

    find查找

    构造数据:

    我们需要构造更多的数据到集合中,这样我们才能很好的讲解查询条件,下面代码你可以直接复制进行添加。当然你也可以自己随意加一些数据到集合中,只要方便我们学习就可以了。

    var workmate1={
      name:'xiaoP',
      age:33,
      sex:1,
      job:'前端',
      skill:{
          skillOne:'HTML+CSS',
          skillTwo:'JavaScript',
          skillThree:'PHP'
      },
      regeditTime:new Date(),
      interest:[]
    }
    var workmate2={
      name:'ShengLei',
      age:31,
      sex:1,
      job:'JAVA后端',
      skill:{
          skillOne:'HTML+CSS',
          skillTwo:'J2EE',
          skillThree:'PPT'
      },
      regeditTime:new Date(),
      interest:[]
    }
    var workmate3={
      name:'MinJie',
      age:18,
      sex:0,
      job:'UI',
      skill:{
          skillOne:'PhotoShop',
          skillTwo:'UI',
          skillThree:'PPT'
      },
      regeditTime:new Date(),
      interest:[]
    }
    var workmate4={
      name:'XiaoWang',
      age:25,
      sex:1,
      job:'UI',
      skill:{
          skillOne:'PhotoShop',
          skillTwo:'UI',
          skillThree:'PPT'
      },
      regeditTime:new Date(),
      interest:[]
    }
    var workmate5={
      name:'LiangPeng',
      age:28,
      sex:1,
      job:'前端',
      skill:{
          skillOne:'HTML+CSS',
          skillTwo:'JavaScript',
      },
      regeditTime:new Date(),
      interest:[]
    }
    var workmate6={
      name:'HouFei',
      age:25,
      sex:0,
      job:'前端',
      skill:{
          skillOne:'HTML+CSS',
          skillTwo:'JavaScript',
      },
      regeditTime:new Date(),
      interest:[]
    }
    var workmate7={
      name:'LiuYan',
      age:35,
      sex:0,
      job:'美工',
      skill:{
          skillOne:'PhotoShop',
          skillTwo:'CAD',
      },
      regeditTime:new Date(),
      interest:[]
    }
    var workmate8={
      name:'DingLu',
      age:20,
      sex:0,
      job:'美工',
      skill:{
          skillOne:'PhotoShop',
          skillTwo:'CAD',
      },
      regeditTime:new Date(),
      interest:[]
    }
    var workmate9={
      name:'JiaPeng',
      age:29,
      sex:1,
      job:'前端',
      skill:{
          skillOne:'HTML+CSS',
          skillTwo:'JavaScript',
          skillThree:'PHP'
      },
      regeditTime:new Date(),
      interest:[]
    }
    var workmate10={
      name:'LiJia',
      age:26,
      sex:0,
      job:'前端',
      skill:{
          skillOne:'HTML+CSS',
          skillTwo:'JavaScript',
          skillThree:'PHP'
      },
      regeditTime:new Date(),
      interest:[]
    }
    var db=connect('company');
    var workmateArray=[workmate1,workmate2,workmate3,workmate4,workmate5,workmate6,workmate7,workmate8,workmate9,workmate10];
    db.workmate.insert(workmateArray);
    print('[SUCCESS]:The data was inserted successfully');
    

    简单查找:

    比如我们要查找数据中技能一为HTML+CSS的所有人。

    db.workmate.find({"skill.skillOne":"HTML+CSS"})
    

    筛选字段:

    现在返回来的数据项太多,太乱,有时候我们的程序并不需要这么多选项。比如我们只需要姓名和技能就可以了。这时候我们需要写第二个参数,看下面的代码。

    db.workmate.find(
        {"skill.skillOne":"HTML+CSS"},
        {name:true,"skill.skillOne":true}
    )
    

    你在终端会看到如下结果:

    { "_id" : ObjectId("5d9d388744beb55a978f0068"), "name" : "xiaoP", "skill" : { "s
    killOne" : "HTML+CSS" } }
    { "_id" : ObjectId("5d9d388744beb55a978f0069"), "name" : "ShengLei", "skill" : {
     "skillOne" : "HTML+CSS" } }
    { "_id" : ObjectId("5d9d388744beb55a978f006c"), "name" : "LiangPeng", "skill" :
    { "skillOne" : "HTML+CSS" } }
    { "_id" : ObjectId("5d9d388744beb55a978f006d"), "name" : "HouFei", "skill" : { "
    skillOne" : "HTML+CSS" } }
    { "_id" : ObjectId("5d9d388744beb55a978f0070"), "name" : "JiaPeng", "skill" : {
    "skillOne" : "HTML+CSS" } }
    { "_id" : ObjectId("5d9d388744beb55a978f0071"), "name" : "LiJia", "skill" : { "s
    killOne" : "HTML+CSS" } }
    

    然后你会发现多了一个ID字段,这个也不是我们想要的,这时候只要把_id:false就可以了。当然这里的false和true,也可以用0和1表示。

    db.workmate.find(
        {"skill.skillOne":"HTML+CSS"},
        {name:true,"skill.skillOne":true,_id:false}
    )
    

    这个时候你在终端查看结果,已经是我们想要的了。

    { "name" : "xiaoP", "skill" : { "skillOne" : "HTML+CSS" } }
    { "name" : "ShengLei", "skill" : { "skillOne" : "HTML+CSS" } }
    { "name" : "LiangPeng", "skill" : { "skillOne" : "HTML+CSS" } }
    { "name" : "HouFei", "skill" : { "skillOne" : "HTML+CSS" } }
    { "name" : "JiaPeng", "skill" : { "skillOne" : "HTML+CSS" } }
    { "name" : "LiJia", "skill" : { "skillOne" : "HTML+CSS" } }
    

    不等修饰符

    如果你以前操作过关系型数据库,比如MySql,你会对>大于),<(小于),=(等于)这些东西很熟悉,但是非关系型数据库不能直接使用这些符号,稍有区别。

    • 小于($lt):英文全称less-than
    • 小于等于($lte):英文全称less-than-equal
    • 大于($gt):英文全称greater-than
    • 大于等于($gte):英文全称greater-than-equal
    • 不等于($ne):英文全称not-equal

    我们现在要查找一下,公司内年龄小于30大于25岁的人员。看下面的代码。

    db.workmate.find(
        {age:{$lte:30,$gte:25}},
        {name:true,age:true,"skill.skillOne":true,_id:false}
    )
    

    日期查找

    MongoDB也提供了方便的日期查找方法,现在我们要查找注册日期大于2018年1月10日的数据,我们可以这样写代码。

    先声明一个日期变量,然后把使用大于符进行筛选。

    var startDate= new Date('01/01/2018');
    db.workmate.find(
        {regeditTime:{$gt:startDate}},
        {name:true,age:true,"skill.skillOne":true,_id:false}
    )
    

    find多条件查找

    很多时候我们需要查询的值不只是有一个简单的条件,比如我们现在要查询一下同事中是33岁和25岁的,还比如我们要查询同事中大于30岁并且会PHP技能的。MongoDB在这方面也支持的很好,我们来学习一下。

    $in修饰符

    in修饰符可以轻松解决一键多值的查询情况。就如上面我们讲的例子,现在要查询同事中年龄是25岁和33岁的信息。

    db.workmate.find({age:{$in:[25,33]}},
        {name:1,"skill.skillOne":1,age:1,_id:0}
    )
    

    in相对的修饰符是nin,就是查询除了$in条件以外的值

    $or修饰符

    它用来查询多个键值的情况,就比如查询同事中大于30岁或者会做PHP的信息,$in修饰符是一个Key值。

    db.workmate.find({$or:[
        {age:{$gte:30}},
        {"skill.skillThree":'PHP'}
    ]},
        {name:1,"skill.skillThree":1,age:1,_id:0}
    )
    

    $and修饰符

    $and用来查找几个key值都满足的情况,比如要查询同事中大于30岁并且会做PHP的信息,这时需要注意的是这两项必须全部满足。当然写法还是比较简单的。只要把上面代码中的or换成and就可以了。

    db.workmate.find({$and:[
        {age:{$gte:30}},
        {"skill.skillThree":'PHP'}
    ]},
        {name:1,"skill.skillThree":1,age:1,_id:0}
    )
    

    $not修饰符

    它用来查询除条件之外的值,比如我们现在要查找除年龄大于20岁,小于30岁的人员信息。需要注意的是$not修饰符不能应用在条件语句中,只能在外边进行查询使用。

    db.workmate.find({
        age:{
            $not:{
                $lte:30,
                $gte:20
            }
        }
    },
    {name:1,"skill.skillOne":1,age:1,_id:0}
    )
    

    find的数组查询

    完善数据

    以前的我们的workmate集合对数组涉及还很少,现在在数据中加入了兴趣(interest),并且给每个人加入了一些兴趣,比如有写代码,做饭,看电影…..

    把之前的数据表drop掉,重新载入addData2.js的数据,数据内容如下:

    var workmate1={
      name:'xiaoP',
      age:33,
      sex:1,
      job:'前端',
      skill:{
          skillOne:'HTML+CSS',
          skillTwo:'JavaScript',
          skillThree:'PHP'
      },
      regeditTime:new Date(),
      interest:['看电影','看书','吃美食','钓鱼','旅游']
    }
    
    var workmate2={
      name:'ShengLei',
      age:31,
      sex:1,
      job:'JAVA后端',
      skill:{
          skillOne:'HTML+CSS',
          skillTwo:'J2EE',
          skillThree:'PPT'
      },
      regeditTime:new Date(),
      interest:['篮球','看电影','做饭']
    }
    
    var workmate3={
      name:'MinJie',
      age:18,
      sex:0,
      job:'UI',
      skill:{
          skillOne:'PhotoShop',
          skillTwo:'UI',
          skillThree:'PPT'
      },
      regeditTime:new Date(),
      interest:['做饭','画画','看电影']
    }
    var workmate4={
      name:'XiaoWang',
      age:25,
      sex:1,
      job:'UI',
      skill:{
          skillOne:'PhotoShop',
          skillTwo:'UI',
          skillThree:'PPT'
      },
      regeditTime:new Date(),
      interest:['写代码','篮球','画画']
    }
    var workmate5={
      name:'LiangPeng',
      age:28,
      sex:1,
      job:'前端',
      skill:{
          skillOne:'HTML+CSS',
          skillTwo:'JavaScript',
      },
      regeditTime:new Date(),
      interest:['玩游戏','写代码','做饭']
    }
    
    var workmate6={
      name:'HouFei',
      age:25,
      sex:0,
      job:'前端',
      skill:{
          skillOne:'HTML+CSS',
          skillTwo:'JavaScript',
      },
      regeditTime:new Date(),
      interest:['化妆','读书','做饭']
    }
    
    var workmate7={
      name:'LiuYan',
      age:35,
      sex:0,
      job:'美工',
      skill:{
          skillOne:'PhotoShop',
          skillTwo:'CAD',
      },
      regeditTime:new Date(),
      interest:['画画','聚会','看电影']
    }
    
    
    var workmate8={
      name:'DingLu',
      age:20,
      sex:0,
      job:'美工',
      skill:{
          skillOne:'PhotoShop',
          skillTwo:'CAD',
      },
      regeditTime:new Date(),
      interest:['美食','看电影','做饭']
    }
    
    var workmate9={
      name:'JiaPeng',
      age:29,
      sex:1,
      job:'前端',
      skill:{
          skillOne:'HTML+CSS',
          skillTwo:'JavaScript',
          skillThree:'PHP'
      },
      regeditTime:new Date(),
      interest:['写代码','篮球','游泳']
    }
    
    var workmate10={
      name:'LiJia',
      age:26,
      sex:0,
      job:'前端',
      skill:{
          skillOne:'HTML+CSS',
          skillTwo:'JavaScript',
          skillThree:'PHP'
      },
      regeditTime:new Date(),
      interest:['玩游戏','美食','篮球']
    }
    
    
    
    var db=connect('company');
    var workmateArray=[workmate1,workmate2,workmate3,workmate4,workmate5,workmate6,workmate7,workmate8,workmate9,workmate10];
    db.workmate.insert(workmateArray);
    print('[SUCCESS]:The data was inserted successfully');
    

    基本数组查询

    比如我们想要查找兴趣爱好是“看电影”的同事,我们使用下面代码查询一下:

    db.workmate.find({interest:['看电影']},
        {name:1,interest:1,age:1,_id:0} 
    )
    

    运行后,并没有如我们所愿得到相应的人员数据,数据为空。那问题出现在哪里?问题就在于我们写了一个中括号([]),因为加上中括号就相当于完全匹配了,所以没有得到一条符合查询条件的数据。我们去掉中括号再看看结果。

    db.workmate.find({interest:'看电影'},
        {name:1,interest:1,age:1,_id:0} 
    )
    

    结果:

    { "name" : "xiaoP", "age" : 33, "interest" : [ "看电影", "看书", "吃美食", "钓鱼
    ", "旅游" ] }
    { "name" : "ShengLei", "age" : 31, "interest" : [ "篮球", "看电影", "做饭" ] }
    { "name" : "MinJie", "age" : 18, "interest" : [ "做饭", "画画", "看电影" ] }
    { "name" : "LiuYan", "age" : 35, "interest" : [ "画画", "聚会", "看电影" ] }
    { "name" : "DingLu", "age" : 20, "interest" : [ "美食", "看电影", "做饭" ] }
    

    这就是我们在数组中查询一项的方法,这也是数组查询的最简单用法。

    $all-数组多项查询

    如果要查询出喜欢看电影和看书的人员信息,也就是对数组中的对象进行查询,这时候要用到一个新的查询修饰符$all。看下面的例子:

    db.workmate.find(
        {interest:{$all:["看电影","看书"]}},
        {name:1,interest:1,age:1,_id:0} 
    )
    

    结果:

    { "name" : "xiaoP", "age" : 33, "interest" : [ "看电影", "看书", "吃美食", "钓鱼
    ", "旅游" ] }
    

    这时候找到了兴趣中既有看电影又有看书的人员。

    $size修饰符

    该修饰符可以根据数组的数量查询出结果。比如现在我们要查找兴趣的数量是5个人员信息,这时候就可以使用$size。

    db.workmate.find(
        {interest:{$size:5}},
        {name:1,interest:1,age:1,_id:0} 
    )
    

    这时候是5项爱好的人员就会显示出来了。

    $slice-显示选项

    有时候我并不需要显示出数组中的所有值,而是只显示前两项,比如我们现在想显示每个人兴趣的前两项,而不是把每个人所有的兴趣都显示出来。

    db.workmate.find(
        {},
        {name:1,interest:{$slice:2},age:1,_id:0} 
    )
    

    这时候就显示出了每个人兴趣的前两项,如果我们想显示兴趣的最后一项,可以直接使用slice:-1,来进行查询。

    find的参数使用方法

    以上所说的都是在操作find方法的第一个参数(query)和第二个参数(fields)。find还有几个常用的参数,这些参数多用在分页和排序上,下面实现一个分页的效果。

    find参数:

    • query:这个就是查询条件,MongoDB默认的第一个参数。
    • fields:(返回内容)查询出来后显示的结果样式,可以用true和false控制是否显示。
    • limit:返回的数量,后边跟数字,控制每次查询返回的结果数量。
    • skip:跳过多少个显示,和limit结合可以实现分页。
    • sort:排序方式,从小到大排序使用1,从大到小排序使用-1。

    分页Demo:

    我们把同事集合(collections)进行分页,每页显示两个,并且按照年龄从小到大的顺序排列。

    db.workmate.find({},{name:true,age:true,_id:false}).limit(0).skip(2).sort({age:1});
    

    结果:

    { "name" : "XiaoWang", "age" : 25 }
    { "name" : "HouFei", "age" : 25 }
    { "name" : "LiJia", "age" : 26 }
    { "name" : "LiangPeng", "age" : 28 }
    { "name" : "JiaPeng", "age" : 29 }
    { "name" : "ShengLei", "age" : 31 }
    { "name" : "xiaoP", "age" : 33 }
    { "name" : "LiuYan", "age" : 35 }
    

    find如何在js文本中使用

    之前的find操作都是在命令行运行的,现在我们想在通过运行js执行,可以使用下面的方法:

    var db = connect("company")  //进行链接对应的集合collections
    var result = db.workmate.find() //声明变量result,并把查询结果赋值给result
    //利用forEach进行循环输出结果。
    result.forEach(function(result){
        printjson(result)
    })
    

    索引

    创建大量的数据(200万条)

    //生成随机数
     
    function GetRandomNum(min,max){
        let range = max-min;   //得到随机数区间
        let rand = Math.random(); //得到随机值
        return (min + Math.round(rand *range)); //最小值+随机数取整
    }
     
    //console.log(GetRandomNum(10000,99999));
     
    //生成随机用户名
    function GetRadomUserName(min,max){
        let tempStringArray= "123456789qwertyuiopasdfghjklzxcvbnm".split("");//构造生成时的字母库数组
        let outPuttext = ""; //最后输出的变量
        //进行循环,随机生产用户名的长度,这里需要生成随机数方法的配合
        for(let i=1 ;i<GetRandomNum(min,max);i++){
            //随机抽取字母,拼装成需要的用户名
            outPuttext=outPuttext+tempStringArray[GetRandomNum(0,tempStringArray.length)]
        }
        return outPuttext;
    }
     
    // console.log(GetRadomUserName(7,16))
    // var startTime=(new Date()).getTime();
    var db = connect('company');
    db.randomInfo.drop();
    var  tempInfo = [];
    for (let i=0;i<2000000;i++){
        tempInfo.push({
            username:GetRadomUserName(7,16),
            regeditTime:new Date(),
            randNum0:GetRandomNum(100000,999999),
            randNum1:GetRandomNum(100000,999999),
            randNum2:GetRandomNum(100000,999999),
            randNum3:GetRandomNum(100000,999999),
            randNum4:GetRandomNum(100000,999999),
            randNum5:GetRandomNum(100000,999999),
            randNum6:GetRandomNum(100000,999999),
            randNum7:GetRandomNum(100000,999999),
            randNum8:GetRandomNum(100000,999999),
            randNum8:GetRandomNum(100000,999999),
        })
    }
     
    db.randomInfo.insert(tempInfo);
    

    执行addData3.js代码。插入数据完成后,我们可以使用 db.randomInfo.stats() 这个命令查看数据中的数据条数。

    普通查询性能

    我们先制作一个普通查询,随便查找一个用户名,并计算出查询和打印的时间,因为有200万条数据,所以性能不会很高。

    var startTime = new Date().getTime()  //得到程序运行的开始时间
    var  db = connect('company')          //链接数据库
    var   rs=db.randomInfo.find({username:"tfruhjy8k"})  //根据用户名查找用户
    rs.forEach(rs=>{printjson(rs)})                     //循环输出
    var  runTime = new Date().getTime()-startTime;      //得到程序运行时间
    print('[SUCCESS]This run time is:'+runTime+'ms')    //打印出运行时间
    

    上边的代码就是一个普通的查询,最后记录了时间。

    建立索引

    试着为用户名(username)建立索引。建立索引只需要一句话就可以了。

    db.randomInfo.ensureIndex({username:1})

    查看已有的索引

    db.randomInfo.getIndexes()

    结果:

    [
            {
                    "v" : 2,
                    "key" : {
                            "_id" : 1
                    },
                    "name" : "_id_",
                    "ns" : "company.randomInfo"
            },
            {
                    "v" : 2,
                    "key" : {
                            "username" : 1
                    },
                    "name" : "username_1",
                    "ns" : "company.randomInfo"
            }
    ]
    

    目前有两条索引,一个是id,在创建数据的时候就存在的索引,username_1是我们自己创建的索引。

    然后我们在来执行以下上面的查询语句,看一下现在多少秒可以查询出来。会发现查询性能确实得到了提升。但索引这东西是要消耗硬盘和内存资源的,所以还是要根据程序需要进行建立了。

    管理:用户的创建、删除与修改

    安装好MongoDB时,它为我们默认开了一个最高管理权限方便我们管理数据库,我们可以用mongo链接数据库,就是这个原理。但在实际开发中并一般不能使用这个用户,因为大家都知道和最高权限的原因,安全性和可靠性都不适合,所以要对MongoDB的用户进行管理。这节课我们就学习一下MongoDB的用户管理。

    创建用户:

    首先要进入我们的admin库中,进入方法是直接使用use admin 就可以。进入后可以使用show collections来查看数据库中的集合。默认是只有一个集合的(system.version)。

    创建用户可以用db.createUser方法来完成,里边参数还是蛮多的,代码我写在下边,然后对每一项做出了解释。

    db.createUser({
        user:"ddlh",
        pwd:"123456",
        customData:{
            name:'段花花',
            email:'666@163.com',
            age:18,
        },
        roles:['read']
    })
    
    db.createUser({
        user:"duan",
        pwd:"123456",
        customData:{
            name:'段',
            email:'666@163.com',
            age:18,
        },
        roles:[
            {
                role:"readWrite",
                db:"log"
            },
            'read'
        ]
    })
    

    内置角色:

    • 数据库用户角色:read、readWrite;
    • 数据库管理角色:dbAdmin、dbOwner、userAdmin;
    • 集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManage;
    • 备份恢复角色:backup、restore;
    • 所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
    • 超级用户角色:root
    • 内部角色:__system

    查找用户信息

    我们直接可以使用查找的方法,查找用户信息。命令很简单:

    db.system.users.find()
    

    删除用户:

    删除用户也是非常简单,直接用remove就可以删除这个用户的信息和权限。

    db.system.users.remove({user:"ddlh"})
    

    建权:

    有时候我们要验证用户的用户名密码是否正确,就需要用到MongoDB提供的健全操作。也算是一种登录操作,不过MongoDB把这叫做建权。

    db.auth("ddlh","123456")
    

    如果正确返回1,如果错误返回0。(Error:Authentication failed。)

    启动建权

    重启MongoDB服务器,然后设置必须使用建权登录。

    mongod --auth
    

    启动后,用户登录只能用用户名和密码进行登录,原来的mongo形式链接已经不起作用了。相应的用户权限也对应妥当。实际项目中我们启动服务器必须使用建权形式。

    登录

    如果在配置用户之后,用户想登录,可以使用mongo的形式,不过需要配置用户名密码:

    mongo  -u ddlh -p 123456 127.0.0.1:27017/admin
    mongo  -u duan -p 123456 127.0.0.1:27017/log
    

    这时候我们就可以用给我们的权限对数据库操作了。

    管理:数据备份(mongodump)与恢复(mongorestore)

    比如现在我们备份所有MongoDB里的库到D盘的databack文件夹下,就可以把命令写成这样

    mongodump --host 127.0.0.1 --port 27017 --out D:/databack/
    

    数据恢复

    mongorestore --host 127.0.0.1 --port 27017 D:/databack/
    

    tips:更多内容建议自己探索及发现,完结。

    相关文章

      网友评论

          本文标题:2. Mongo基本命令操作

          本文链接:https://www.haomeiwen.com/subject/kgfipctx.html