mongodb 基础 命令 学习

1. window+r mongod  启动
2. 查看现有的数据库 show dbs
3. 进入数据库 use xxxx    switched to db simle-vue  进入成功
4. 显示当前数据库 集合(关系表) show collections
5. 显示当前位置 db
6. 建立数据库  use db xxxx  
7. 新建集合 和插入文件(数据)   db.集合.insert()   demo:db.user.insert({"name":"jspang"})
8. 查询所有数据  demo:db.user.find()
9. 查询第一个文件数据  demo:db.user.findOne()
10. 修改文件数据 demo:db.集合.update({查询},{修改})  db.jspang.update({"name":"jspang"},{"name":"jspang","age":"32"})
11. 删除文件数据 demo:db.user.remove({"name":"jspang"})
12. 删除整个集合 db.user.drop()
13. 删除整个数据库 db.dropDatabase()
14. $set修改器  用来修改一个指定的键值(key),这时候我们要修改上节课的sex和age就非常方便了,只要一句话就可以搞定。
15. $unset用于将key删除   它的作用其实就是删除一个key值和键。一般女孩子都是不希望看到自己的年龄的,所以要求我们把年龄删除。
    这时候我们就可以使用$unset的形式  当你删除后,想加回来可以直接用set进行添加。
16. multi选项  db.workmate.update({},{$set:{interset:[]}},{multi:true})   添加兴趣爱好  这时候每个数据都发生了改变,
    multi是有ture和false两个值,true代表全部修改,false代表只修改一个(默认值)
17. upsert选项  upsert是在找不到值的情况下,直接插入这条数据。比如我们这时候又来了一个新同事xiaoWang,我们这时候修改他的信息,age设置成20岁,
    但集合中并没有这条数据。这时候可以使用upsert选项直接添加
    db.workmate.update({name:'xiaoWang'},{$set:{age:20}},{upsert:true})  upsert也有两个值:true代表没有就添加,false代表没有不添加(默认值)。
18. 修改:update数组修改器  ---- $push追加数组/内嵌文档值 $push的功能是追加数组中的值,但我们也经常用它操作内嵌稳文档,就是{}对象型的值。
    先看一个追加数组值的方式,比如我们要给小王加上一个爱好(interset)为画画(draw)
    db.workmate.update({name:'xiaoWang'},{$push:{interest:'draw'}})  当然$push修饰符还可以为内嵌文档增加值,比如我们现在要给我们的UI,
    增加一项新的技能skillFour为draw,这时候我们可以操作为:
    db.workmate.update({name:'MinJie'},{$push:{"skill.skillFour":'draw'}})
    $push修饰符在工作中是最常用的,因为我们的数据一般都会涉及数组和内嵌文档的操作,一定要掌握。
19. $ne查找是否存在  它主要的作用是,检查一个值是否存在,如果不存在再执行操作,存在就不执行,这个很容易弄反,记得我刚学的时候就经常弄反这个修改器的作用,给自己增加了很多坑。
    例子:如果xiaoWang的爱好(interest)里没有palyGame这个值,我们就加入Game这个爱好。 总结:没有则修改,有则不修改。
20. $addToSet 升级版的$ne  它是$ne的升级版本(查找是否存在,不存在就push上去),操作起来更直观和方便,所以再工作中这个要比$en用的多。
    例子:我们现在要查看小王(xiaoWang)兴趣(interest)中有没有阅读(readBook)这项,没有则加入读书(readBook)的兴趣.
    db.workmate.update({name:"xiaoWang"},{$addToSet:{interest:"readBook"}})
21. $each 批量追加  它可以传入一个数组,一次增加多个值进去,相当于批量操作,性能同样比循环操作要好很多,这个是需要我们注意的,工作中也要先组合成数组,然后用批量的形式进行操作。    
    例子:我们现在要给xiaoWang,一次加入三个爱好,唱歌(Sing),跳舞(Dance),编码(Code)。
    var newInterset=["Sing","Dance","Code"];
    db.workmate.update({name:"xiaoWang"},{$addToSet:{interest:{$each:newInterset}}})
22. $pop 删除数组值  
    $pop只删除一次,并不是删除所有数组中的值。而且它有两个选项,一个是1和-1。
    1:从数组末端进行删除
    -1:从数组开端进行删除
    例子:现在要删除xiaoWang的编码爱好(code)。
    db.workmate.update({name:'xiaoWang'},{$pop:{interest:1}})
23. 数组定位修改  有时候只知道修改数组的第几位,但并不知道是什么,这时候我们可以使用interest.int 的形式。
    例子,比如我们现在要修改xiaoWang的第三个兴趣为编码(Code),注意这里的计数是从0开始的。
24. 修改:状态返回与安全  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" : 1,
        "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
25. findAndModify:从名字上就可以看出,findAndModify是查找并修改的意思。配置它可以在修改后给我们返回修改的结果。我们先看下面的代码:
    var myModify={
    findAndModify:"workmate",
    query:{name:'JSPang'},
    update:{$set:{age:18}},
        new:true    //更新完成,需要查看结果,如果为false不进行查看结果
    }
    var ResultMessage=db.runCommand(myModify);
    printjson(ResultMessage)
    findAndModify的性能是没有直接使用db.collections.update的性能好,但是在实际工作中都是使用它,毕竟要商用的程序安全性还是比较重要的。
    findAndModify属性值:

    query:需要查询的条件/文档
    sort: 进行排序
    remove:[boolean]是否删除查找到的文档,值填写true,可以删除。
    new:[boolean]返回更新前的文档还是更新后的文档。
    fields:需要返回的字段
    upsert:没有这个值是否增加。
    总结:这节课讲了一些跟安全有关的操作,但这不是全部,我们随着课程的深入还会继续学习更多的知识。工作中尽量使用findAndModify来进行更新数据,
    这样会更安全和直观,这点性能的损失是值得的。
26. 查询:find的不等修饰符 MongoDB的查找操作我们会分几节课来讲,因为内容还是比较多的,而且在开发中查找是应用最多的操作,几乎每个模块都会用到,
    所以查找的部分将是本套课的重中之重。这节课我们先来看看简单的查询条件,也了解一下find基础用法。
    如果你以前操作过关系型数据库,比如MySql,你会对>大于),<(小于),=(等于)这些东西很熟悉,但是非关系型数据库不能直接使用这些符号,稍有区别。
    构造数据:
    我们需要构造更多的数据到集合中,这样我们才能很好的讲解查询条件,下面代码你可以直接复制进行添加。当然你也可以自己随意加一些数据到集合中,只要方便我们学习就可以了。
    var workmate1={
        name:'JSPang',
        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');

27. 简单查找:
    比如我们现在要查找数据中技能一会HTML+CSS的所有人。那我们直接进行查找加条件就可以了。
    db.workmate.find({"skill.skillOne":"HTML+CSS"})
    这时候我们不能使用load来载入了,以后我会给大家讲使用的方法,这里先用比较笨的方法,使用粘贴复制的方法执行。
28. 筛选字段 现在返回来的数据项太多,太乱,有时候我们的程序并不需要这么多选项。比如我们只需要姓名和技能就可以了。这时候我们需要写第二个参数,看下面的代码。
    db.workmate.find(
        {"skill.skillOne":"HTML+CSS"},
        {name:true,"skill.skillOne":true}
    )
    你会在终端中看到如下结果:
    { "_id" : ObjectId("5a611350c4e36dee6008987a"), "name" : "JSPang", "skill" : { "skillOne" : "HTML+CSS" } }
    { "_id" : ObjectId("5a611350c4e36dee6008987b"), "name" : "ShengLei", "skill" : { "skillOne" : "HTML+CSS" } }
    { "_id" : ObjectId("5a611350c4e36dee6008987e"), "name" : "LiangPeng", "skill" : { "skillOne" : "HTML+CSS" } }
    { "_id" : ObjectId("5a611350c4e36dee6008987f"), "name" : "HouFei", "skill" : { "skillOne" : "HTML+CSS" } }
    { "_id" : ObjectId("5a611350c4e36dee60089882"), "name" : "JiaPeng", "skill" : { "skillOne" : "HTML+CSS" } }
    { "_id" : ObjectId("5a611350c4e36dee60089883"), "name" : "LiJia", "skill" : { "skillOne" : "HTML+CSS" } }
    细心的小伙伴会发现还不够完美,多了一个ID字段,这个也不是我们想要的,这时候只要把_id:false就可以了。当然这里的false和true,也可以用0和1表示。
    db.workmate.find(
        {"skill.skillOne":"HTML+CSS"},
        {name:true,"skill.skillOne":true,_id:false}
    )
    这时候你在终端中查看结果,已经是我们想要的了。
    { "name" : "JSPang", "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" } }
    其实这些查找操作,都是在作等于的阶段,但是不光只有等于查询,我们需要更多的查询条件。
29. 不等修饰符
    小于($lt):英文全称less-than
    小于等于($lte):英文全称less-than-equal
    大于($gt):英文全称greater-than
    大于等于($gte):英文全称greater-than-equal
    不等于($ne):英文全称not-equal 我们现在要查找一下,公司内年龄小于30大于25岁的人员。看下面的代码。
30. 日期查找
    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}
    )
    结果:
    { "name" : "JSPang", "age" : 18, "skill" : { "skillOne" : "HTML+CSS" } }
    { "name" : "ShengLei", "age" : 30, "skill" : { "skillOne" : "HTML+CSS" } }
    { "name" : "MinJie", "skill" : { "skillOne" : "PhotoShop" } }
    { "name" : "JSPang", "age" : 33, "skill" : { "skillOne" : "HTML+CSS" } }
    { "name" : "ShengLei", "age" : 31, "skill" : { "skillOne" : "HTML+CSS" } }
    { "name" : "MinJie", "age" : 18, "skill" : { "skillOne" : "PhotoShop" } }
    { "name" : "XiaoWang", "age" : 25, "skill" : { "skillOne" : "PhotoShop" } }
    { "name" : "LiangPeng", "age" : 28, "skill" : { "skillOne" : "HTML+CSS" } }
    { "name" : "HouFei", "age" : 25, "skill" : { "skillOne" : "HTML+CSS" } }
    { "name" : "LiuYan", "age" : 35, "skill" : { "skillOne" : "PhotoShop" } }
    { "name" : "DingLu", "age" : 20, "skill" : { "skillOne" : "PhotoShop" } }
    { "name" : "JiaPeng", "age" : 29, "skill" : { "skillOne" : "HTML+CSS" } }
    { "name" : "LiJia", "age" : 26, "skill" : { "skillOne" : "HTML+CSS" } }
    我们先生命了一个日期变量,然后把使用大于符进行筛选。
    总结:这节课内容并不多,但如果你是个DBA(数据库管理员)工作中每天都会用到,所以这节课的内容练习是必须的,如果你懒得动手,那接下来的课程你可能无法学会。
31. 查询:find的多条件查询
    很多时候我们需要查询的值不只是有一个简单的条件,比如我们现在要查询一下同事中是33岁和25岁的,还比如我们要查询同事中大于30岁并且会PHP技能的。
    MongoDB在这方面也支持的很好,我们来学习一下。
32. $in修饰符
    $in修饰符可以轻松解决一键多值的查询情况。就如上面我们讲的例子,现在要查询同事中年龄是25岁和33岁的信息。
    db.workmate.find({age:{$in:[25,33]}},
        {name:1,"skill.skillOne":1,age:1,_id:0}
    )
    于$in相对的修饰符是$nin,就是查询除了$in条件以为的指,小伙伴们可以自己进行练习一下,这里我就不作过多的演示了。
33. $or修饰符
    它用来查询多个键值的情况,就比如查询同事中大于30岁或者会做PHP的信息。主要区别是两个Key值。$in修饰符是一个Key值,这个需要去比较记忆。
    db.workmate.find({$or:[
        {age:{$gte:30}},
        {"skill.skillThree":'PHP'}
    ]},
        {name:1,"skill.skillThree":1,age:1,_id:0}
    )
    or很好理解,就是或者的意思,我们查出来的结果也是一样的,查出了年龄大于30岁的,或者会做PHP的信息。相对应的还有$nor修饰符,这里不作演示了,自己试验一下。
34. $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}
    )
35. $not修饰符
    它用来查询除条件之外的值,比如我们现在要查找除年龄大于20岁,小于30岁的人员信息。需要注意的是$not修饰符不能应用在条件语句中,只能在外边进行查询使用。
    db.workmate.find({
        age:{
            $not:{
                $lte:30,
                $gte:20
            }
        }
    },
    {name:1,"skill.skillOne":1,age:1,_id:0}
    )
36. 查询:find的数组查询
    重新 载入数据
    var workmate1={
        name:'JSPang',
        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');
37. 基本数组查询
    比如现在我们知道了一个人的爱好是’画画’,’聚会’,’看电影’,但我们不知道是谁,这时候我们就可以使用最简单的数组查询(实际工作中,这种情况基本不常用,
    所以这种查询只作知识点储备就可以了)。
    db.workmate.find({interest:['画画','聚会','看电影']},
        {name:1,interest:1,age:1,_id:0} 
    )
    在终端中运行后,我们得到了数据。这时候我们说,想查出看兴趣中有看电影的员工信息。按照正常逻辑,应该使用下面的代码。
    db.workmate.find({interest:['看电影']},
        {name:1,interest:1,age:1,_id:0} 
    )
    运行后,并没有如我们所愿得到相应的人员数据,数据为空。那问题出现在哪里?
    问题就在于我们写了一个中括号([]),因为加上中括号就相当于完全匹配了,所以没有得到一条符合查询条件的数据。我们去掉中括号再看看结果。
    db.workmate.find({interest:'看电影'},
        {name:1,interest:1,age:1,_id:0} 
    )
    这就是我们在数组中查询一项的方法,这也是数组查询的最简单用法。
38. $all-数组多项查询
    现在我们的条件升级了,要查询出喜欢看电影和看书的人员信息,也就是对数组中的对象进行查询,这时候要用到一个新的查询修饰符$all。看下面的例子:
    db.workmate.find(
        {interest:{$all:["看电影","看书"]}},
        {name:1,interest:1,age:1,_id:0} 
    )
    这时候找到了兴趣中既有看电影又有看书的人员。
39. $in-数组的或者查询
    用$all修饰符,是需要满足所有条件的,$in主要满足数组中的一项就可以被查出来(有时候会跟$or弄混)。比如现在要查询爱好中有看电影的或者看书的员工信息。
    db.workmate.find(
        {interest:{$in:["看电影","看书"]}},
        {name:1,interest:1,age:1,_id:0} 
    )
40. $size-数组个数查询
    $size修饰符可以根据数组的数量查询出结果。比如现在我们要查找兴趣的数量是5个人员信息,这时候就可以使用$size。
    db.workmate.find(
        {interest:{$size:5}},
        {name:1,interest:1,age:1,_id:0} 
    )
    这时候是5项爱好的人员就会显示出来了。
41. $slice-显示选项
    有时候我并不需要显示出数组中的所有值,而是只显示前两项,比如我们现在想显示每个人兴趣的前两项,而不是把每个人所有的兴趣都显示出来。\
    db.workmate.find(
        {},
        {name:1,interest:{$slice:2},age:1,_id:0} 
    )
    这时候就显示出了每个人兴趣的前两项,如果我们想显示兴趣的最后一项,可以直接使用slice:-1,来进行查询。
    总结:如果你只看视频一定学不会,程序这东西必须要动手练习,我在所有的视频中都反复强调,目的没有别的就是想让你们真的学会,并应用到工作中去。
42. 查询:find的参数使用方法
    前边已经讲了3节查询,都是在操作find方法的第一个参数(query)和第二个参数(fields)。find还有几个常用的参数,
    这些参数多用在分页和排序上。这节我们就把这些常用的选项说一说,理解后我们演示一个分页的效果。\
    find参数:
    query:这个就是查询条件,MongoDB默认的第一个参数。
    fields:(返回内容)查询出来后显示的结果样式,可以用true和false控制是否显示。
    limit:返回的数量,后边跟数字,控制每次查询返回的结果数量。
    skip:跳过多少个显示,和limit结合可以实现分页。
    sort:排序方式,从小到大排序使用1,从大到小排序使用-1。
43. 分页Demo:明白了上面这些选项,现在可以作一个最简单的分页,我们把同事集合(collections)进行分页,每页显示两个,并且按照年龄从小到大的顺序排列。
    { "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" : "JSPang", "age" : 33 }
    { "name" : "LiuYan", "age" : 35 }
44. $where修饰符
    它是一个非常强大的修饰符,但强大的背后也意味着有风险存在。它可以让我们在条件里使用javascript的方法来进行复杂查询。我们先来看一个最简单的例子,现在要查询年龄大于30岁的人员。
    db.workmate.find(
        {$where:"this.age>30"},
        {name:true,age:true,_id:false}
    )
    这里的this指向的是workmate(查询集合)本身。这样我们就可以在程序中随意调用。虽然强大和灵活,但是这种查询对于数据库的压力和安全性都会变重,所以在工作中尽量减少$where修饰符的使用。
45. 查询:find如何在js文本中使用
    前边使用find都是JS在文本中写完,然后复制到终端中执行,这样非常麻烦。在讲的过程中已经有很多小伙伴在问我如何像写update语句一样,
    在文本中直接运行。这节课我们就学习一下如何直接在文本中执行。
    hasNext循环结果  想在文本中执行我们的find语句要用到游标和循环的操作,先看一下代码,代码中我已经对每一句进行了注释。
    var db = connect("company")  //进行链接对应的集合collections
    var result = db.workmate.find() //声明变量result,并把查询结果赋值给result
    //利用游标的hasNext()进行循环输出结果。
    while(result.hasNext()){
        printjson(result.next())  //用json格式打印结果
    }
    结果:
    {
            "_id" : ObjectId("5fb78572e0656126ed7c277a"),
            "name" : "JSPang",
            "age" : 33,
            "sex" : 1,
            "job" : "前端",
            "skill" : {
                    "skillOne" : "HTML+CSS",
                    "skillTwo" : "JavaScript",
                    "skillThree" : "PHP"
            },
            "regeditTime" : ISODate("2020-11-20T08:59:30.411Z"),
            "interest" : [
                    "看电影",
                    "看书",
                    "吃美食",
                    "钓鱼",
                    "旅游"
            ]
    }
    {
            "_id" : ObjectId("5fb78572e0656126ed7c277b"),
            "name" : "ShengLei",
            "age" : 31,
            "sex" : 1,
            "job" : "JAVA后端",
            "skill" : {
                    "skillOne" : "HTML+CSS",
                    "skillTwo" : "J2EE",
                    "skillThree" : "PPT"
            },
            "regeditTime" : ISODate("2020-11-20T08:59:30.411Z"),
            "interest" : [
                    "篮球",
                    "看电影",
                    "做饭"
            ]
    }
    {
            "_id" : ObjectId("5fb78572e0656126ed7c277c"),
            "name" : "MinJie",
            "age" : 18,
            "sex" : 0,
            "job" : "UI",
            "skill" : {
                    "skillOne" : "PhotoShop",
                    "skillTwo" : "UI",
                    "skillThree" : "PPT"
            },
            "regeditTime" : ISODate("2020-11-20T08:59:30.411Z"),
            "interest" : [
                    "做饭",
                    "画画",
                    "看电影"
            ]
    }
    {
            "_id" : ObjectId("5fb78572e0656126ed7c277d"),
            "name" : "XiaoWang",
            "age" : 25,
            "sex" : 1,
            "job" : "UI",
            "skill" : {
                    "skillOne" : "PhotoShop",
                    "skillTwo" : "UI",
                    "skillThree" : "PPT"
            },
            "regeditTime" : ISODate("2020-11-20T08:59:30.411Z"),
            "interest" : [
                    "写代码",
                    "篮球",
                    "画画"
            ]
    }
    {
            "_id" : ObjectId("5fb78572e0656126ed7c277e"),
            "name" : "LiangPeng",
            "age" : 28,
            "sex" : 1,
            "job" : "前端",
            "skill" : {
                    "skillOne" : "HTML+CSS",
                    "skillTwo" : "JavaScript"
            },
            "regeditTime" : ISODate("2020-11-20T08:59:30.411Z"),
            "interest" : [
                    "玩游戏",
                    "写代码",
                    "做饭"
            ]
    }
    {
            "_id" : ObjectId("5fb78572e0656126ed7c277f"),
            "name" : "HouFei",
            "age" : 25,
            "sex" : 0,
            "job" : "前端",
            "skill" : {
                    "skillOne" : "HTML+CSS",
                    "skillTwo" : "JavaScript"
            },
            "regeditTime" : ISODate("2020-11-20T08:59:30.411Z"),
            "interest" : [
                    "化妆",
                    "读书",
                    "做饭"
            ]
    }
    {
            "_id" : ObjectId("5fb78572e0656126ed7c2780"),
            "name" : "LiuYan",
            "age" : 35,
            "sex" : 0,
            "job" : "美工",
            "skill" : {
                    "skillOne" : "PhotoShop",
                    "skillTwo" : "CAD"
            },
            "regeditTime" : ISODate("2020-11-20T08:59:30.411Z"),
            "interest" : [
                    "画画",
                    "聚会",
                    "看电影"
            ]
    }
    {
            "_id" : ObjectId("5fb78572e0656126ed7c2781"),
            "name" : "DingLu",
            "age" : 20,
            "sex" : 0,
            "job" : "美工",
            "skill" : {
                    "skillOne" : "PhotoShop",
                    "skillTwo" : "CAD"
            },
            "regeditTime" : ISODate("2020-11-20T08:59:30.411Z"),
            "interest" : [
                    "美食",
                    "看电影",
                    "做饭"
            ]
    }
    {
            "_id" : ObjectId("5fb78572e0656126ed7c2782"),
            "name" : "JiaPeng",
            "age" : 29,
            "sex" : 1,
            "job" : "前端",
            "skill" : {
                    "skillOne" : "HTML+CSS",
                    "skillTwo" : "JavaScript",
                    "skillThree" : "PHP"
            },
            "regeditTime" : ISODate("2020-11-20T08:59:30.411Z"),
            "interest" : [
                    "写代码",
                    "篮球",
                    "游泳"
            ]
    }
    {
            "_id" : ObjectId("5fb78572e0656126ed7c2783"),
            "name" : "LiJia",
            "age" : 26,
            "sex" : 0,
            "job" : "前端",
            "skill" : {
                    "skillOne" : "HTML+CSS",
                    "skillTwo" : "JavaScript",
                    "skillThree" : "PHP"
            },
            "regeditTime" : ISODate("2020-11-20T08:59:30.411Z"),
            "interest" : [
                    "玩游戏",
                    "美食",
                    "篮球"
            ]
    }
46. 写完后,现在你只需要在终端中进行load()就可以执行了,再也不用麻烦的复制粘贴了。
    forEach循环
    利用hasNext循环结果,需要借助while的帮助,MongoDB也为我们提供了forEach循环,现在修改上边的代码,使用forEach循环来输出结果。
    var db = connect("company")  //进行链接对应的集合collections
    var result = db.workmate.find() //声明变量result,并把查询结果赋值给result
    //利用游标的hasNext()进行循环输出结果。
    result.forEach(function(result){
        printjson(result)
    })
    作为个人觉的forEach循环更为优雅。这两种方法都是非常不错的,凭借自己爱好进行选择吧。
    总结:那我们MongoDB的基础部分就全部讲完了,我们学会了它的增、删、改、查,你也可以使用MongoDB进行一些操作了。需要注意的是,
    只是这篇文章的完结,下篇文章我们进行讲解MongoDB,开始讲解MongoDB的索引。
47. 索引:构造百万级数据
    索引的性能提现必须要有大量数据才能看出来,你说你有10条20条数据,这是根本看不出来效果的,这节课就通过随机数的方法,创造出一个百万级数据的数据库出来。(建议收看视频学习)。
    制作随机数方法:
    我们要想生成一个百万级的数据集合,必须要有随机数的参与,我们需要写一个随机数的方法。下面的代码,创建了一个随机数方法。
    //生成随机数
    function GetRandomNum(min,max){
        let range = max-min;   //得到随机数区间
        let rand = Math.random(); //得到随机值
        return (min + Math.round(rand *range)); //最小值+随机数取整
    }
    console.log(GetRandomNum(10000,99999));
    制作随机用户名:
    有了随机数的方法,我们就可以制作一个随机生成的用户名。目的是存在不同的用户名,方便我们测试查询速度。
    //生成随机数
    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))
    插入200万数据
    有了生成随机数和随机用户名的方法,就可以生产百万级数据了。此处代码会在视频中作详细讲解。代码如下:
    总结:这节课主要是为讲解MongoDB的索引作准备,我们用随机数的方法构建了一个百万级的数据表,如果你有兴趣继续往下学习联系,这节课必须动手作一下。以后这篇文章的学习全是基于这个代码。
48. 索引:索引入门
    集合中已经有了200万条的数据,可以进行索引的操作了。我们先来建立一个索引,然后看看它的查询性能到底提升了多少倍。这节课的内容不会很难,主要掌握索引的建立方法即可。
    普通查询性能
    我们先制作一个普通查询,随便查找一个用户名,并计算出查询和打印的时间,因为有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')    //打印出运行时间
    上边的代码就是一个普通的查询,只不过是记录了时间。在终端运行后,可以得到大概的运行时间是0.8秒左右(电脑性能不同,有所不同),
    第一次无缓存的运行时间大概是3.5秒左右。这个时间是没办法满足我们的日常查询的。
49. 建立索引
    试着为用户名(username)建立索引。建立索引只需要一句话就可以了。
    db.randomInfo.ensureIndex({username:1})
    查看现有索引
    db.randomInfo.getIndexes()
    终端的结果,现在只有一个索引值:
    [
            {
                    "v" : 2,
                    "key" : {
                            "_id" : 1
                    },
                    "name" : "_id_",
                    "ns" : "company.randomInfo"
            }
    ]
    那现在使用命令建立一下索引db.randomInfo.ensureIndex({uername:1}),我的电脑大概要50秒左右,建立好后我们重新使用db.randomInfo.getIndexes(),查看一下结果。
    结果如下:已经变成了两条索引。
    [
            {
                    "v" : 2,
                    "key" : {
                            "_id" : 1
                    },
                    "name" : "_id_",
                    "ns" : "company.randomInfo"
            },
            {
                    "v" : 2,
                    "key" : {
                            "username" : 1
                    },
                    "name" : "uername_1",
                    "ns" : "company.randomInfo"
            }
    ]
    然后我们在来load一下demo07.js文件(load(‘./demo07.js’)),看一下现在多少秒可以查询出来。这时候查询的时间缩短到了4ms左右,查询性能提升了大概200倍左右。
    总结:无论是在关系型数据库还是文档数据库,建立索引都是非常重要的。前边讲了,索引这东西是要消耗硬盘和内存资源的,所以还是要根据程序需要进行建立了。MongoDB也给我们进行了限制,只允许我们建立64个索引值。
50. 索引:复合索引
    这节课先来看看什么样的数据你使用索引会变慢,然后学习一下复合索引的使用和语法。通过这节课我们需要对所以使用的时机有所了解,避免画蛇添足,产生不必的麻烦。
    索引中的小坑
    记得我刚学MongoDB时,学会了索引,我就到处想用,甚至几百条数据的集合(collections),我也自作聪明的用一下,但结果往往是画蛇添足,走了不少弯路。通过实际开发和性能对比,我自己总结了几条不用索引的情况(不一定对,但是自己的经验之谈)。
    数据不超万条时,不需要使用索引。性能的提升并不明显,而大大增加了内存和硬盘的消耗。
    查询数据超过表数据量30%时,不要使用索引字段查询。实际证明会比不使用索引更慢,因为它大量检索了索引表和我们原表。
    数字索引,要比字符串索引快的多,在百万级甚至千万级数据量面前,使用数字索引是个明确的选择。
    把你经常查询的数据做成一个内嵌数据(对象型的数据),然后集体进行索引。\
    复合索引
    好了上边我们讲了一大堆理论,现在来看复合索引。复合索引就是两条以上的索引。上节课我们已经把username字段建立了索引,我们现在把randNum0,这个字段也设置成索引。
    建立好后,我们再用查询索引状态命令进行查询。
    db.randomInfo.getIndexes()
    这时候已经是两个自建索引了,一共有三个索引。
    [
            {
                    "v" : 2,
                    "key" : {
                            "_id" : 1
                    },
                    "name" : "_id_",
                    "ns" : "company.randomInfo"
            },
            {
                    "v" : 2,
                    "key" : {
                            "username" : 1
                    },
                    "name" : "username_1",
                    "ns" : "company.randomInfo"
            },
            {
                    "v" : 2,
                    "key" : {
                            "randNum0" : 1
                    },
                    "name" : "randNum0_1",
                    "ns" : "company.randomInfo"
            }
    ]
51. 两个索引同时查询
    我们同时查询两个索引的值,看看效果是怎么样的。
    var startTime=new Date().getTime();
    var db = connect('company');
    var  rs= db.randomInfo.find({username:'7xwb8y3',randNum0:565509});
    rs.forEach(rs=>{printjson(rs)});
    var runTime = new Date().getTime()-startTime;
    print('[Demo]this run time is '+runTime+'ms');
    从性能上看并没有什么特殊的变化,查询时间还是在4ms左右。MongoDB的复合查询是按照我们的索引顺序进行查询的。就是我们用db.randomInfo.getIndexes()查询出的数组。
    指定索引查询(hint)
    课程开始时,我说了数字的索引要比字符串的索引快,这就需要一个方法来打破索引表的查询顺序,用我们自己指定的索引优先查询,这个方法就是hint().
    var  rs= db.randomInfo.find({username:'7xwb8y3',randNum0:565509}).hint({randNum0:1});
    由于数据量和复杂成都还是不大,所以你看不出来明显的性能提升,但是要相信技术胖,等工作中遇到大数据时,一定会得到很好的效果的。
    var startTime=new Date().getTime();
    var db = connect('company');
    var  rs= db.randomInfo.find({username:'7xwb8y3',randNum0:565509}).hint({randNum0:1});
    rs.forEach(rs=>{printjson(rs)});
    var runTime = new Date().getTime()-startTime;
    print('[Demo]this run time is '+runTime+'ms');
52. 删除索引
    当索引性能不佳或起不到作用时,我们需要删除索引,删除索引的命令是dropIndex().
    db.randomInfo.dropIndex('randNum0_1');//索引的唯一ID
    这里需要注意的是删除时填写的值,并不是我们的字段名称(key),而是我们索引查询表中的name值。这是一个小坑,希望小伙伴们不要踩中。
    总结:这节主要内容还是操作索引,包括复合索引的建立,删除。和一些使用索引的小窍门。
53. 索引:全文索引
    有些时候需要在大篇幅的文章中搜索关键词,比如我写的文章每篇都在万字以上,这时候你想搜索关键字是非常不容易的,MongoDB为我们提供了全文索引。
    准备工作:
    这节我们先建立一个集合(collections)-info,然后插入一小段文章,作用就是为建立全文索引提供数据,当然我们不再建立百万级数据,我们只是看一下效果。
    db.info.insert({contextInfo:"I am a programmer, I love life, love family. Every day after work, I write a diary."})
    db.info.insert({contextInfo:"I am a programmer, I love PlayGame, love drink. Every day after work, I playGame and drink."})
    当然这很简单,再次强调这只是文章需要,实际工作中这么简单的数据没必要建立全文索引。

    建立全文索引
    db.info.ensureIndex({contextInfo:'text'})
    {
            "createdCollectionAutomatically" : false,
            "numIndexesBefore" : 1,
            "numIndexesAfter" : 2,
            "ok" : 1
    }
    需要注意的是这里使用text关键词来代表全文索引,我们在这里就不建立数据模型了。
    全文索引查找 建立好了全文索引就可以查找了,查找时需要两个关键修饰符:
    $text:表示要在全文索引中查东西。
    $search:后边跟查找的内容。
    db.info.find({$text:{$search:"programmer"}})
54. 查找多个词
    全文索引是支持多个次查找的,比如我们希望查找数据中有programmer,family,diary,drink的数据(这是或的关系),所以两条数据都会出现。
    db.info.find({$text:{$search:"programmer family diary drink"}})
    如果我们这时候希望不查找出来有drink这个单词的记录,我们可以使用“-”减号来取消。
    db.info.find({$text:{$search:"programmer family diary -drink"}})
55. 转义符:全文搜索中是支持转义符的,比如我们想搜索的是两个词(love PlayGame和drink),这时候需要使用\斜杠来转意。
    db.info.find({$text:{$search:"\"love PlayGame\" drink"}})
    总结:全文索引在工作还是经常使用的,比如博客文章的搜索,长文件的关键词搜索,这些都需要使用全文索引来进行。
    这节课的知识并不难,还是那句话,你看是不可能学会的,一定要动手练习。
    当然索引还有很多知识,这里我们只讲最常用的知识,把小伙伴引入门就好,也就是常说的用20%的精力,学会80%的知识,然后在工作中进行迭代磨练。
    虽然MongoDB的索引文章结束了,但是MongoDB的文章还没有结束,下篇文章开始学习如何管理MongoDB。
56. 管理:用户的创建、删除与修改
    安装好MongoDB时,它为我们默认开了一个最高管理权限方便我们管理数据库,我们可以用mongo链接数据库,就是这个原理。
    但在实际开发中并一般不能使用这个用户,因为大家都知道和最高权限的原因,安全性和可靠性都不适合,所以要对MongoDB的用户进行管理。
    这节课我们就学习一下MongoDB的用户管理。
57. 创建用户:
    首先要进入我们的admin库中,进入方法是直接使用use admin 就可以。进入后可以使用show collections来查看数据库中的集合。默认是只有一个集合的(system.version)。
    创建用户可以用db.createUser方法来完成,里边参数还是蛮多的,代码我写在下边,然后对每一项做出了解释。
    db.createUser({
        user:"jspang",
        pwd:"123456",
        customData:{
            name:'技术胖',
            email:'web0432@126.com',
            age:18,
        },
        roles:['read']
    })
    当然我们还可以单独配置一个数据库的权限,比如我们现在要配置compay数据库的权限为读写:
    db.createUser({
        user:"jspang",
        pwd:"123456",
        customData:{
            name:'技术胖',
            email:'web0432@126.com',
            age:18,
        },
        roles:[
            {
                role:"readWrite",
                db:"company"
            },
            'read'
        ]
    })
    内置角色:

    数据库用户角色:read、readWrite;
    数据库管理角色:dbAdmin、dbOwner、userAdmin;
    集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManage;
    备份恢复角色:backup、restore;
    所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
    超级用户角色:root
    内部角色:__system
58. 查找用户信息
    我们直接可以使用查找的方法,查找用户信息。命令很简单: 
    db.system.users.find()
59. 删除用户:删除命令也是非常简单,直接用remove就可以删除这个用户的信息和权限。
    db.system.users.remove({user:"jspang"})
60. 建权:
    有时候我们要验证用户的用户名密码是否正确,就需要用到MongoDB提供的健全操作。也算是一种登录操作,不过MongoDB把这叫做建权。
    db.auth("jspang","123456")
    如果正确返回1,如果错误返回0。(Error:Authentication failed。)
61. 启动建权

    重启MongoDB服务器,然后设置必须使用建权登录。
    mongod --auth
    启动后,用户登录只能用用户名和密码进行登录,原来的mongo形式链接已经不起作用
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值