资讯专栏INFORMATION COLUMN

练习 MongoDB 操作 —— 数据操作(一)

printempw / 344人阅读

摘要:本文的目标是通过大量的示例,来更好的理解如果在中进行数据操作初入客户端刚利用命令进入客户端环境,此时对数据库一无所知举目四望,想知道现在有哪些数据库,因为是新装的环境,所以只看到了和两个默认就存在的数据库目光慢慢收回,那么当前是处于哪个数据

本文的目标是通过大量的示例,来更好的理解如果在Mongodb中进行数据操作;

初入客户端
刚利用 mongod命令进入客户端环境,此时对数据库一无所知;

举目四望,想知道现在有哪些数据库,

show dbs;

因为是新装的mongodb环境,所以只看到了adminlocal两个默认就存在的数据库;目光慢慢收回,那么当前是处于哪个数据库上呢?

db;

通过上述这个命令,不仅可以知道当前在哪个数据库上;
现在切换到admin数据库上,转一圈;

use admin;

数据库
这时候,笔者想要创建自己应用的数据库school, 用来存放一些班级学生信息;

use school;

use命令:如果数据库不存在,则创建数据库,否则切换到指定数据库;

突然发现刚才敲命令,写错了,写成了use school1;这时候,希望删除school1这个数据库,就切换到该数据库下,再键入删除命令;

use school1;
db.dropDatabase();

集合
Mongodb中的集合相当于Mysql中的表;

作为一名优秀的“校长”,能适应高信息化社会发展,笔者需要为学校下的各个年级、班级建立集合;创建集合可以是显式的,也可以是隐式的;

通过show tables,看到数据库下没有任何集合;笔者显式地创建“一年级一班的”集合;

db.createCollection("grade_1_1");

再次通过show tables就可以看到列表中有grade_1_1这个集合;

当然,也可以隐式地创建,当为集合插入数据,集合不存在,这时候集合会自动创建;现在,不存在grade_1_2“一年级二班”这个集合,执行下面语句,为“一年级二班”加入一个学生;

db.grade_1_2.insert({"name": "zhangsan", "age": "7", "sex": "0"});

通过show tables就可以看到grade_1_2这个集合了;

因为一些特殊原因,要解散一年级二班,那笔者这儿就不用继续维护grade_1_2集合,

db.grade_1_2.drop();
练习增查

清空上面的school数据库

use school;
db.dropDatabase();
use school;
show tables;

创建一年级的3个班,并随机添加 10 名学生;

   for(grade_index in (grade = ["grade_1_1", "grade_1_2", "grade_1_3"])) {
       for (var i = 1; i <= 10; i++) {
           db[grade[grade_index]].insert({
               "name": "zhangsan" + i,
               "sex": Math.round(Math.random() * 10) % 2,
               "age": Math.round(Math.random() * 6) + 3,
               "hobby": []
           });
       }
   }

查看一年级二班grade_1_2中的所有学生

db.getCollection("grade_1_2").find({})

查看一年级二班grade_1_2中所有年龄是 4 岁的学生

db.getCollection("grade_1_2").find({"age": 4})

查看一年级二班grade_1_2中所有年龄大于 4 岁的学生

db.getCollection("grade_1_2").find({"age": {$gt: 4}})

查看一年级二班grade_1_2中所有年龄大于 4 岁并且小于 7 岁的学生

db.getCollection("grade_1_2").find({"age": {$gt: 4, $lt: 7}})

查看一年级二班grade_1_2中所有年龄大于 4 岁并且性别值为0的学生

db.getCollection("grade_1_2").find({"age": {$gt: 4}, "sex": 0})

查看一年级二班grade_1_2中所有年龄小于 4 岁并且大于 7 岁的学生

db.getCollection("grade_1_2").find({$or: [{"age": {$lt: 4}}, {"age": {$gt: 6}}]})

查看一年级二班grade_1_2中所有年龄是 4 岁或 6 岁的学生

db.getCollection("grade_1_2").find({"age": {$in: [4, 6]}})

查看一年级二班grade_1_2中所有姓名带zhangsan1的学生

db.getCollection("grade_1_2").find({"name": {$regex: "zhangsan1"}})

查看一年级二班grade_1_2中所有姓名带zhangsan1zhangsan2的学生

db.getCollection("grade_1_2").find({"name": {
   $in: [new RegExp(""zhangsan1"), new RegExp(""zhangsan2")]
}})

查看一年级二班grade_1_2中所有兴趣爱好有三项的学生

db.getCollection("grade_1_2").find({"hobby": {$size: 3}})
查看一年级二班`grade_1_2`中所有兴趣爱好包括画画的学生
db.getCollection("grade_1_2").find({"hobby": "drawing"})
查看一年级二班`grade_1_2`中所有兴趣爱好既包括画画又包括跳舞的学生
db.getCollection("grade_1_2").find({"hobby": {$all: ["drawing", "dance"]}})

查看一年级二班grade_1_2中所有兴趣爱好有三项的学生的学生数目

db.getCollection("grade_1_2").find({"hobby": {$size: 3}}).count()

查看一年级二班的第二位学生

db.getCollection("grade_1_2").find({}).limit(1).skip(1)

查看一年级二班的学生,按年纪升序

db.getCollection("grade_1_2").find({}).sort({"age": 1})
查看一年级二班的学生,按年纪降序
db.getCollection("grade_1_2").find({}).sort({"age": -1})

查看一年级二班的学生,年龄值有哪些

db.getCollection("grade_1_2").distinct("age")
查看一年级二班的学生,兴趣覆盖范围有哪些
db.getCollection("grade_1_2").distinct("hobby")
查看一年级二班的学生,男生(`sex`为 0)年龄值有哪些
 db.getCollection("grade_1_2").distinct("age", {"sex": 0})

练习删除

一年级二班grade_1_2, 删除所有 4 岁的学生

db.getCollection("grade_1_2").remove({"age": 4})

一年级二班grade_1_2, 删除第一位 6 岁的学生

db.getCollection("grade_1_2").remove({"age": 6}, {justOne: 1})

练习修改

一年级二班grade_1_2中,修改名为zhangsan7的学生,年龄为 8 岁,兴趣爱好为 跳舞和画画;

db.getCollection("grade_1_2").update({"name": "zhangsan7"}, {$set: {"age": 8, "hobby": ["dance", "drawing"]}})
 一年级二班`grade_1_2`中,追加zhangsan7`学生兴趣爱好唱歌;
db.getCollection("grade_1_2").update({"name": "zhangsan7"}, {$push: {"hobby": "sing"}})
 一年级二班`grade_1_2`中,追加zhangsan7`学生兴趣爱好吹牛和打篮球;
db.getCollection("grade_1_2").update({"name": "zhangsan7"}, {$push: {"hobby": {$each: ["brag", "play_basketball"]}}})
 一年级二班`grade_1_2`中,追加`zhangsan7`学生兴趣爱好唱歌和打篮球,要保证`hobby`数组不重复;
 db.getCollection("grade_1_2").update({"name": "zhangsan7"}, {$addToSet: {"hobby": {$each: ["sing1", "play_basketball"]}}})

新学年,给一年级二班所有学生的年龄都增加一岁

 db.getCollection("grade_1_2").update({}, {$inc: {"age": 1}}, {multi: true})

一年级二班grade_1_2中,删除zhangsan7学生的sex属性

 db.getCollection("grade_1_2").update({"name": "zhangsan7"}, {$unset: {"sex": 1}})

一年级二班grade_1_2中,删除zhangsan7学生的hobby数组中的头元素

 db.getCollection("grade_1_2").update({"name": "zhangsan7"}, {$pop: {"hobby": -1}})
 一年级二班`grade_1_2`中,删除`zhangsan7`学生的`hobby`数组中的尾元素
 db.getCollection("grade_1_2").update({"name": "zhangsan7"}, {$pop: {"hobby": 1}})
 一年级二班`grade_1_2`中,删除`zhangsan7`学生的`hobby`数组中的`sing`元素
 db.getCollection("grade_1_2").update({"name": "zhangsan7"}, {$pull: {"hobby": "sing"}})

练习分组

新建一个集合grade_1_4,记录一年级四班在期中考试时的成绩;

    for (var i = 1; i <= 10; i++) {
        db.grade_1_4.insert({
            "name": "zhangsan" + i,
            "sex": Math.round(Math.random() * 10) % 2,
            "age": Math.round(Math.random() * 6) + 3,
            "score": {
                "chinese": 60 + Math.round(Math.random() * 40),
                "math": 60 + Math.round(Math.random() * 40),
                "english": 60 + Math.round(Math.random() * 40)
            }
        });
    }

统计每名学生在考试中的总分

   db.grade_1_4.group({
       key: {"name": 1},
       cond: {},
       reduce: function(curr, result) {
result.total += curr.score.chinese + curr.score.math + curr.score.english;
       },
       initial: { total : 0 }
   })

统计每名男生在考试中的总分

   db.grade_1_4.group({
       key: {"name": 1},
       cond: {"sex": 0},
       reduce: function(curr, result) {
result.total += curr.score.chinese + curr.score.math + curr.score.english;
       },
       initial: { total : 0 }
   })

统计每名男生在考试中的总分及平均分

   db.grade_1_4.group({
       key: {"name": 1},
       cond: {"sex": 0},
       reduce: function(curr, result) {
result.total += curr.score.chinese + curr.score.math + curr.score.english;
       },
       initial: { total : 0 },
       finalize: function(item) {
item.avg = (item.total / 3).toFixed(2);
return item;
       }
   })

练习聚合

根据姓名分组, 并统计人数

   db.getCollection("grade_1_4").aggregate([
       {$group: {_id: "$name", num: {$sum: 1}}}
   ])
 根据姓名分组, 并统计人数,过滤人数大于 1 的学生
   db.getCollection("grade_1_4").aggregate([
       {$group: {_id: "$name", num: {$sum: 1}}}, 
       {$match: {num: {$gt: 1}}}
   ])

统计每名学生在考试中的总分

   db.getCollection("grade_1_4").aggregate([
       {$group: {_id: "$name", score: {$sum: {$sum: ["$score.chinese", "$score.math", "$score.english"]}}}}
])

统计每名男生在考试中的总分

db.getCollection("grade_1_4").aggregate([
   {$match: {sex: 0}},
   {$group: {_id: "$name", score: {$sum: {$sum: ["$score.chinese", "$score.math", "$score.english"]}}}}
])
统计每名男生在考试中的总分, 总分降序
   db.getCollection("grade_1_4").aggregate([
       {$match: {sex: 0}},
       {$group: {_id: "$name", score: {$sum: {$sum: ["$score.chinese", "$score.math", "$score.english"]}}}},
       {$sort: {score: 1}}
])

练习权限 创建用户

要让权限生效,需要mongo服务器启动时添加--auth选项;

创建用户school_admin,只能对school数据库进行读写操作;

use school;

db.createUser({
    user: "school_admin",
    pwd: "school_admin",
    roles: [{role: "readWrite", db: "school"}]
})

关于第三个参数角色,看下表:

角色名 描述
Read 允许用户读取指定数据库
readWrite 允许用户读写指定数据库
dbAdmin 允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile
userAdmin 允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户
clusterAdmin 只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限
readAnyDatabase 只在admin数据库中可用,赋予用户所有数据库的读权限
readWriteAnyDatabase 只在admin数据库中可用,赋予用户所有数据库的读写权限
userAdminAnyDatabase 只在admin数据库中可用,赋予用户所有数据库的userAdmin权限
dbAdminAnyDatabase 只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限
root 只在admin数据库中可用。超级账号,超级权限
验证用户

如果未通过验证,进行查询,

会得到如下的提示:

Error: error: {
    "ok" : 0,
    "errmsg" : "not authorized on school to execute command { find: "grade_1_2", filter: {} }",
    "code" : 13,
    "codeName" : "Unauthorized"
}

如果执行验证代码:注意,要在注册时所在的数据库中验证

use school;

db.auth("用户名", "密码")
查看所有用户
db.getUsers()
删除用户

先移到用户注册的数据库,然后移除指定用户 school_admin

db.dropUser("school_admin")

关于用户的注册位置,笔者的理解是在admin下创建其他数据库的管理者,再由这些管理者在对应的数据库下创建“可读”或“可写”的用户;

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/19116.html

相关文章

  • 练习 MongoDB 操作 —— 索引篇(二)

    摘要:所以,如果你很少对集合进行读取操作,建议不使用索引内存使用由于索引是存储在内存中你应该确保该索引的大小不超过内存的限制。如果索引的大小大于内存的限制,会删除一些索引,这将导致性能下降。 本文围绕索引、游标两部分进行探索,对MongoDB数据库的索引部分有一个大概的了解; 索引 索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符...

    luqiuwen 评论0 收藏0
  • Vue+Koa+Mongodb练习

    摘要:小练习作者本文首发博客功能基于进行登录,注册,留言的简单网站。所以这个小练习,从一个简单的方面入手,希望能给踩过同样多坑的同路人一点启发。就意味着要重新登录。的作用是进行进程守护,当你的意外的停止的时候,进行重启。 Vue+Koa+Mongodb 小练习 作者: Pawn 本文首发: Pawn博客 功能: 基于vue koa mongodb进行登录,注册,留言的简单网站。 体验地址: ...

    赵春朋 评论0 收藏0
  • 基于 Vue2+Node+mongoDB 的前后端分离全栈练手小项目

    摘要:本文源码简介之前刚入门并做好了一个简而全的纯全家桶的项目,数据都是本地模拟请求的详情请移步这里为了真正做到数据库的真实存取,于是又开始入门了并以此来为之前的页面写后台数据接口。 本文源码:Github 简介: 之前刚入门vue并做好了一个简而全的纯vue2全家桶的项目,数据都是本地 json 模拟请求的;详情请移步这里:vue-proj-demo 为了真正做到数据库的真实存取,于是又...

    jay_tian 评论0 收藏0
  • 些基于React、Vue、Node.js、MongoDB技术栈的实践项目

    摘要:利用中间件实现异步请求,实现两个用户角色实时通信。目前还未深入了解的一些概念。往后会写更多的前后台联通的项目。删除分组会连同组内的所有图片一起删除。算是对自己上次用写后台的一个强化,项目文章在这里。后来一直没动,前些日子才把后续的完善。 欢迎访问我的个人网站:http://www.neroht.com/ 刚学vue和react时,利用业余时间写的关于这两个框架的训练,都相对简单,有的...

    tangr206 评论0 收藏0
  • 用Go语言借助mgo实现个对MongoDB进行增删改查的demo

    摘要:准备数据结构这个以对一个简单的通讯录进行插入查询更新删除记录为例,中包含和两个字段下载还没出官方的驱动包,是现在比较流行的第三方包,能找到的相关资料也比较多。准备实现对的增删改查操作,先想了下怎么写测试案例。查找,通过查找该条记录。 环境声明:go version go1.11MongoDB server version 4.0.3 背景 这是我第一次接触golang和MongoDB,...

    Jingbin_ 评论0 收藏0

发表评论

0条评论

printempw

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<