MongoDB的使用

一、MongoDB简介

  • MongoDB是为快速开发互联网web应用而设计的数据库系统。
  • MongoDB的设计目标是极简、灵活、作为web应用栈的一部分。
  • MongoDB的数据模型是面向文档的,所谓文档是一种类似于JSON的结构,简单理解MongoDB这个数据库中存得是各种各样得JSON。(BSON增强版的json)。

二、MongoDB三个概念

  • 数据库(database):数据库是一个仓库,在仓库中可以存放集合。
  • 集合 (collection):集合类似于数组,在集合中可以存放文档。
  • 文档 (document):文档数据库中的最小单位,我们存储和操作的内容都是文档。

在MongoDB中,数据库和集合豆豆不需要手动创建,当我们创建文档时,如果文档所在的集合或数据库不存在会自动创建数据库和集合。

三、Windows安装MongoDB

参考自己的博文:https://www.cnblogs.com/nastu/p/16271881.html

四、操作Mongo数据库

基本的指令:

#显示当前的所有数据库
show dbs
show databases

#进入到指定的数据库中
use 数据库名

#表示当前所处于哪个数据库
db

#查看数据库里面所有的集合
show collections

数据库的增删改查(CURD)

#向数据库中插入文档
db.<集合名称>.insert(doc)

#向集合中插入一个文档
#例如,向test数据库中的stus集合中插入一个新的学生对象
{name:"孙悟空",age:18,gender:"男"}
#输入以下命令
db.stus.insert({name:"xia",age:22,gender:"male"});

查找集合的文档内容

 db.stus.find()

五、安装MongoDB图形化工具【有很多中工具(Studio 3T)选择适合自己的即可】

下载地址:https://www.mongodbmanager.com/download-mongodb-manager-free

下载之后傻瓜式的安装即可,连接MongoDB数据库

注意:如果遇到无法输入中文直接退出重启一下就可以了。

六、数据库操作

1、插入文档

/*向集合中插入1个文档*/
db.stus.insert({name:"夏天",age:18,gender:"男"});
/*向集合中插入多个文档*/
db.stus.insert([
{name:"小一",age:22,gender:"男"},
{name:"小二",age:22,gender:"女"},
{name:"小三",age:22,gender:"女"}
]);
db.stus.find();
/*生成ID码*/
ObjectId()
/*自定义ID*/
db.stus.insert({_id:"hello",name:"夏天",age:18,gender:"男"});

db.集合名称.insertOne()       #插入一个文档,里面不能有数组

db.集合名称.insertMany()     #插入多个文档,里面必须是数组

2、查询文档

/*
查询  
   db.collection.find()
   - find()用来查询集合中所有符合条件的文档
   - find()可以接收一个对象作为条件参数
       {} 表示查询集合中所有的文档
       {属性名:值} 查询属性是指定值的文档
   - find()返回的是一个数组
   
   db.collection.findOne()
   - 用来查询集合中符合条件的第一个文档
   - findOne()返回的是一个文档对象
   
   db.collection.find({}).count()
   - 查询所有结果的数量
*/
/*查询指定条件的文档,id是hello的文档*/
db.stus.find({_id:"hello"});
/*查询指定条件的文档,age是22,name是小三*/
db.stus.find({age:22,name:"小三"});
/*查询指定条件的文档,age是22,查询数组索引为1的文档*/
db.stus.find({age:22})[1];
/*查询指定条件的文档,age是22,返回的是一个对象*/
db.stus.findOne({age:22});
/*查询所有结果的总数*/
db.stus.find({}).count();

3、修改文档

/*
  修改
  db.collection.update(查询条件、新对象)
    - update()默认情况下会使用新对象来替换旧的对象
    - 如果需要修改指定的属性,而不是替换需要使用"修改操作符"来完成修改
        $set 可以用来修改文档中的指定属性
        $unset 删除文档中指定的属性
    - update 默认情况只会修改一个  
    
  db.collection.updateMany()
    - 同时修改多个符合条件的文档

  db.collection.updateOne()
    - 修改一个符合条件的文档 
 
  db.collection.replaceOne()
    - 替换一个文档 
*/

//查询结果
db.stus.find({});
//替换掉所有的内容,仅剩下age信息
db.stus.update({name:"小三"},{age:1});
//替换指定的某一个或多个内容
db.stus.update(
   {"name":"夏天"},
   {$set:{
    name:"Hello"
    }}
);
//删除文档中指定的一个或多个属性,删除gender属性
db.stus.update(
   {"name":"夏天"},
   {$unset:{
    gender:"男"
    }}
);
//目前小一存在两个,使用updateMany将同时修改两个文档,将其address修改为香港
db.stus.updateMany(
   {"name":"小一"},
   {
     $set:{
           address:"香港"
     }
   }
);
//查询结果
db.stus.find();
//小一有多个的情况下只修改一个
db.stus.updateOne(
   {"name":"小一"},
   {
     $set:{
     address:"香港九龙"
     }
   }
);
//multi:true,也是表示小一有多个的情况下,同时修改多个
db.stus.update(
   {"name":"小一"},
    {
        $set:{
        address:"香港平顶山"
        }
     },
     {
        multi:true
     }  
);

 4、删除文档

/*
    删除
    db.collection.remove()
    - 删除符合条件的所有的文档(默认情况下会删除多个)
        如果remove()第二个参数传递一个true,则只会删除一个
        如果传递空对象则删除所有
    db.collection.deleteOne()
    db.collection.deleteMany()
        - remove()可以根据条件来删除文档,传递的条件的方式和find()一样
    db.collection.drop()删除集合
    db.dropDatabase()删除数据库  
  
        -一般数据库中的数据都不会删除,所以删除的方法很少调用
*/
db.stus.find();
db.stus.remove({_id:"hello"});
//删除name为小一的文档(删除多个)
db.stus.remove({name:"小一"});
//删除name为小二的文档(只删除1个)
db.stus.remove({name:"小二"},true);
//传递空对象则删除所有的文档【清空集合,一个一个删除(性能略差)】
db.stus.remove({});
//清空集合(性能高)
db.stus.drop();

七、练习1

1、进去my_test数据库

show dbs
use my_test
db

2、向数据库的user集合中插入一个文档

db.user.insert({name:"夏天",age:"12",gender:"女"});

3、查询user集合中的文档

show collections
db.user.find();

4、向数据库的user集合中插入一个文档

db.user.insert({name:"春天",age:"14",gender:"女"});

5、查询数据库user集合中的文档

db.user.find();

6、查询数据库user集合中的文档数量

db.user.find().count();

7、查询数据库user集合中name为"春天"的文档

db.user.find({name:"春天"});

8、向数据库user集合中的name为"春天"的文档,添加一个address属性,属性值为"香港"

db.user.update(
    {name:"春天"},
    {$set:{address:"香港"}}
);

9、使用{name:"春天"} 替换 name 为 "张三" 的文档

db.user.update(
    {name:"春天"},
    {$set:{name:"张三"}}
);

10、删除 name 为 张三 的文档的address属性

db.user.update(
    {name:"张三"},
    {$set:{address:"广州"}}
);

11、向name为夏天的文档中,添加一个hobby:{cities:["beijing","shanghai","shenzhen"], movies:["sanguo","hero"]}

db.user.update(
    {name:"夏天"},
    {$set:{hobby:{cities:["beijing","shanghai","shenzhen"], movies:["sanguo","hero"]}}}
);

12、向name为张三的文档中,添加一个hobby:{movies:["A Chinese Odyssey","King of comedy"]}

db.user.update(
    {name:"张三"},
    {$set:{hobby:{movies:["A Chinese Odyssey","King of comedy"]}}}
);

13、查询喜欢的电影hero的文档

MongoDB支持直接通过内嵌文档的属性进行查询,如果要查询内嵌文档则可以通过.的形式匹配
如果要通过内嵌文档来对文档进行查询,此时属性名必须使用引号,对数组或元素进行匹配
db.user.find({'hobby.movies':"hero"});

14、向张三中添加一个新的电影Interstellar

$push 用于向数组中添加一个新的元素
$addToSet 向数组中添加一个新元素,如果数组中已经存在该元素则不会重复添加
db.user.update(
    {name:"张三"},
    {$push:{"hobby.movies":"Interstellar"}}
);
db.user.update(
    {name:"张三"},
    {$addToSet:{"hobby.movies":"Interstellar"}}
);

15、删除喜欢beijing的用户,(删除cities里面包含beijing的用户)

db.user.remove({"hobby.cities":"beijing"});

16、删除user集合

db.user.remove({});
db.user.drop();
show dbs;

17、向numbers中插入2000条数据,使用for循环

for(var i=1; i<=20000; i++){
    db.numbers.insert({num:i});
}
#以上方式效率太低了,每循环一次得insert一次

优化方案:尽量在调取方法之前讲数据处理完再一次性插入数据

var arr = [];
for(var i=1; i<=20000; i++){
    arr.push({num:i});
}
db.numbers.insert(arr);

18、查询numbers中num为500的文档

db.numbers.find({num:500});

19、查询numbers中num大于5000的文档

db.numbers.find({num:{$gt:5000}});
//大于等于5000的文档
db.numbers.find({num:{$gte:5000}});

20、查询numbers中num小于30的文档

db.numbers.find({num:{$lt:30}});
db.numbers.find({num:{$lte:30}});

21、查询numbers中num大于40小于50的文档

db.numbers.find({num:{$gt:40,$lt:50}});

22、查询numbers中num大于19996的文档

db.numbers.find({num:{$gt:19996}});

23、查询numbers集合中的前10条数据

db.numbers.find().limit(10);

24、查询numbers集合中的第11条到20条数据

db.numbers.find().skip(10).limit(10);

25、查询numbers集合中的第21条到30条数据

// skip((页码-1)*每页显示的条数).limit(每页显示的条数);
db.numbers.find().skip(20).limit(10);
// skip与limit的位置可以互换效果一样
db.numbers.find().limit(10).skip(20);

八、数据库文档之间的关系

 1、文档之间的关系:

一对一:在MongoDB,可以通过内嵌文档的形式体现出一对一的关系

db.wifeAndHusband.insert(
    [{name:"黄蓉",husband:{name:"郭靖"}},
     {name:"谢娜",husband:{name:"张杰"}}
    ]
);
db.wifeAndHusband.find();

一对多:也可以通过内嵌文档来映射一对多的关系

db.users.insert(
    [{username:"swk"},
    {username:"zbj"}
    ]);
db.users.find();
    
db.order.insert({
    list:["猪肉","牛肉"],
    user_id:ObjectId("62839c6b07ace0531b630947")
});
db.order.find();

//下面的两句一起执行
//查找用户swk的id 
var user_id = db.users.findOne({username:"swk"})._id;
//查找用户swk的订单
db.order.find({user_id:user_id});

多对多:

db.teachers.insert([
    {name:"张三"},
    {name:"李四"},
    {name:"王五"}
]);
db.teachers.find();

db.stus.insert([
    {name:"张三丰",tech_ids:[ObjectId("6283a5eb07ace0531b63094b"),
                            ObjectId("6283a5eb07ace0531b63094c")]},
    {name:"李易峰",tech_ids:[ObjectId("6283a5eb07ace0531b63094b"),
                            ObjectId("6283a5eb07ace0531b63094d")]}
]);
db.stus.find();

九、练习2

1、讲dept和emp集合导入到数据库中

2、查询工资小于2000的员工

db.emp.find({sal:{$lt:2000}});

3、查询工资在1000-2000之间的员工

db.emp.find({sal:{$lt:2000,$gt:1000}});

4、查询工资小于1000或大于2500的员工

// or表示或,数组里面的一个条件满足则输出
db.emp.find({$or:[{sal:{$lt:1000}},{sal:{$gt:2500}}]})

5、查询财务部的所有员工

//先查财务部的Number,再查财务部的员工
var depno = db.dept.findOne({dname:"财务部"}).deptno;
db.emp.find({depno:depno});

6、查询销售部的所有员工

//先查销售部的Number,再查销售部的员工
var depno = db.dept.findOne({dname:"销售部"}).deptno;
db.emp.find({depno:depno});

7、查询所有mgr为7698的所有员工

db.emp.find({mgr:7698});

8、为所有薪资低于1000的员工增加工资400元

//$inc :表示在原值的基础上增加
db.emp.updateMany({sal:{$lte:1000}},{$inc:{sal:400}});

十、MongoDB 的 sort(升序或倒序)和投影(只显示某些字段)

//limit skip sort 可以以任意的顺序进行调用
//按照sal升序排列
db.emp.find({}).sort({sal:1});
//按照sal倒序排列
db.emp.find({}).sort({sal:-1});
//首先按照sal升序,如果sal一样的则按照empno倒序排列
db.emp.find({}).sort({sal:1,empno:-1});

//在查询时,可以在第二个参数的位置来设置查询结果的 投影
//查询出来的结果只显示ename字段,默认情况下id都有
db.emp.find({},{ename:1});
//查询的结果只显示 ename,sal字段,不显示id字段
db.emp.find({},{ename:1,_id:0,sal:1});

十一、Mongoose简介【程序操作数据库】

1、简介

之前我们都是通过shell来完成对数据库的各种操作的,在开发中大部分时候我们都需要通过程序来完成对数据库的操作。而Mongoose 就是一个让我们可以通过Node来操作MongoDB的模块。Mongoose是一个对象文档模型(ODM)库,它对Node原生的MongoDB模块进行了进一步的优化封装,并提供了更多的功能。在大多数情况下,它被用来把结构化的模型应用到一个MongoDB集合,并提供了验证和类型转换等好处。

2、Mongoose的好处

  • 可以为文档创建一个模式结构(Schema)【数据进入数据库之前,可以对字段进行约束,对数据类型的约束(如果数据类型不对会自动转换)】
  • 可以对模型中的对象/文档进行验证
  • 数据可以通过类型转换转换为对象模型
  • 可以使用中间件来应用业务逻辑挂钩
  • 比Node原生的MongoDB驱动更容易

3、Mongoose新的对象

  • Schema(模式对象):定义约束了数据库中的文档结构
  • Model:作为集合中的所有文档的表示,相当于MongoDB数据库中的集合collection
  • Document:表示集合中的具体文档,相当于集合中的一个具体的文档

4、Mongoose的使用

1)、下载安装Mongoose

  -npm install mongoose

2)、在项目中引入mongoose

  -const mongoose = require("mongoose")

3)、连接MongoDB数据库

  -mongoose.connect("mongodb://数据库IP地址、;端口号/数据库名"),如果端口号是默认的端口号(27017)则可以省略不写

4)、断开连接

       -mongoDB数据库,一般情况下,只需要连接一次,连接一次后,除非项目停止服务器关闭,否则连接一般不会断开 

  -mongoose.disconnect()

 

5、Schema和Model的使用

 

posted @ 2022-05-14 18:02  娜梓  阅读(862)  评论(0编辑  收藏  举报