目录
一、安装 MongoDB
二、将 MongoDB 设置为系统服务
三、MongoDB的基本操作
基本指令
数据库的CRUD(增删改查)初体验
四、可视化管理工具
五、插入文档
六、查询文档
七、修改文档
八、删除文档
九、文档间的关系
十、练习
十一、排序和投影
十二、Mongoose
安装mongoose
Model的方法
Document方法
MongoDB是一个开源、高性能、无模式的文档型数据库,是NoSQL数据库产品中的一种。它的出现主要应对“三高”等问题,它可以解决需要存储数据量大、高并发读写、高可用的现实问题,适用于社交朋友圈、游戏积分、物流轨迹、商品评论等业务。架构成本较低,各方面却很优秀,MongoDB值得您选择。
在MongoDB中,数据库和集合都不需要我们手动创建,当我们创建文档时,如果文档所在的集合或数据库不存在,她会自动创建数据库和集合
1. 显示当前所有数据库
show dbs
show databases
2. 进入到指定的数据库中(不存在的数据库会自动创建)
use 数据库名
3. 表示的是当前所处数据库
db
4. 显示我们数据库中所有的集合
show collections
1. 向集合中插入文档
举例:向test数据库中的stus集合中插入一个新的学生对象
use test
db.stus.insert ( {name:“孙悟空”,age:18,gender:”男“} )
db.集合名.insert(doc)
2. 查询当前集合的所有文档
db.集合名.find()
13个Mongodb GUI可视化管理工具,总有一款适合你_互联网架构的博客-CSDN博客
1. 当我们向集合中插入文档时,如果没有给文档指定_id属性,则数据库会自动给文档添加_id 该属性用来作为文档的唯一标识
2. _id可以自己指定,如果我们指定了,数据库就不会再添加了,如果自己指定_id必须也确保唯一性
db.集合名.insert(doc) 可以拆分为
db.集合名.insertOne(doc) 插入一个对象
db.集合名.insertMany(doc) 插入多个对象
/*
插入一个对象的两种方式
*/
db.stus.insert({ name: "zs", age: 28})
db.stus.insertOne({ name: "zs", age: 28})
/*
插入多个对象的两种方式
*/
db.stus.insert([
{ name: "zs", age: 28},
{ name: "ls", age: 18},
])
db.stus.insertMany([
{ name: "zs", age: 28},
{ name: "ls", age: 18},
])
1. find()用来查询集合中所有符合条件的文档
2. find()可以接收一个对象作为条件参数
- { }:表示所有文档
- { 属性:值 }:查询属性是指定值的文档
- 返回值是一个数组
3. find({}).count() 查询所有结果的数量
3. findOne()
用来查询集合中符合条件的第一个文档
返回的是一个文档对象
db.集合名.find()
db.stus.find({ _id: "hello", age: 20 })
db.stus.find({ _id: "hello", age: 20 })[0]
db.stus.find({}).conut()
db.stus.findOne({ age: 20 })
db.stus.findOne({ _id: "hello", age: 20 }).name
1. db.集合名.update(查询条件,新对象)
- update()默认情况下会使用新对象来替换整个旧对象
- update()默认只会修改一个文档对象,可以增加一个可选属性 multi:true ,即可同时修改多个符合条件的文档对象
2. 如果需要修改指定的属性,而不是替换,需要使用 “修改操作符” 来完成修改
- $set:可以用来修改文档中的指定属性
- $unset:可以用来删除文档的指定属性
3.
- updateMany():同时修改多个符合条件的文档对象
- updateOne():修改一个符合条件的文档
- replaceOne():替换一个符合条件的文档
db.集合名.update(查询条件,新对象)
db.stus.update(
{name:"沙和尚"},
{age:28}
)
db.stus.update(
{"_id" : ObjectId("5f86edc1048d21081bd45f3b")},
{$set:{ gender:"男", address:"流沙河" }}
)
db.stus.update(
{"_id" : ObjectId("5f86edc1048d21081bd45f3b")},
{$unset:{ address:"流沙河" }}
)
db.stus.updateMany(
{"name" :"猪八戒"},
{$set:{ address:"高老庄" }}
)
db.stus.update(
{"name" :"猪八戒"},
{$set:{ address:"呵呵呵" }},
{ multi:true }
)
1. db.集合名.remove()
- 可以根据条件来删除文档,传递条件的方式和find()一样
- 能删除符合条件的所有文档,默认删除多个文档
- 如果第二个参数传递一个true,则只会删除一个文档
- 如果只传递一个{ }作为参数,则会删除集合中的所有文档,清空集合,但集合保留
2.
- deleteOne()删除符合条件的一个文档
- deleteMany()删除符合条件的多个文档
- drop():删除集合(如果删除的是最后一个集合,数据库也会被删除)
3. 一般数据库中的数据都不会删除,所以删除的方法很少调用,一般会在数据中添加一个字段,来表示数据是否被删除
db.stus.remove({age:28},true)
db.stus.remove({}) //性能差
db.stus.drop()
db.dropDatabase()
一对一(one to one)如夫妻关系
- 可以通过内嵌文档体现
MongoDB的文档的属性值也可以是一个文档,当一个文档的属性值是文档对象时,我们称这个文档为内嵌文档
db.WifeAndHusband.insert([
{
wife:"黄蓉",
husband:{
name:"郭靖"
}
},
{
wife:"潘金莲",
husband:{
name:"武大郎"
}
}
])
一对多(one to many)/ 多对一(many to one)如父母和孩子,用户和订单的关系
- 也可以通过内嵌文档的方式
// 在 order 集合插入一条孙悟空的订单
db.order.insert({
list:["watermelor"],
user_id:ObjectId("5f87b1deda684b252c2fc7a5")
})
// 通过 users 集合找到孙悟空的 id
var user_id = db.users.findOne({username:"孙悟空"})._id
//查询孙悟空的订单
db.order.find({user_id:user_id})
多对多(many to many):如分类和商品,老师和学生,通过内嵌文档的方式
db.teacher.insert([
{name:"洪七公"},
{name:"黄药师"},
{name:"龟仙人"}
])
db.stus.insert([
{
name:"郭靖",
tech_ids:[
ObjectId("5f87b4b6da684b252c2fc7a8"),
ObjectId("5f87b4b6da684b252c2fc7a9")
]
},
{
name:"孙悟空",
tech_ids:[
ObjectId("5f87b4b6da684b252c2fc7a8"),
ObjectId("5f87b4b6da684b252c2fc7a9"),
ObjectId("5f87b4b6da684b252c2fc7aa")
]
}
])
//这样添加的两万条数据的性能高,尽量少调用系统的方法
var arr=[];
for(var i=1;i<=20000;i++){
arr.push({num:i});
}
db.numbers.insert(arr);
//查询numbers中num大于500的文档
db.numbers.find({num:{$gt:500}})
//查询numbers中num小于30的文档
db.numbers.find({num:{$lt:30}})
//查询numbers中num大于40小于50的文档
db.numbers.find({num:{$gt:40,$lt:50}})
//查询numbers前10条的数据
db.numbers.find({num:{$lte:10}})
//limit()设置显示数据的上限
db.numbers.find().limit(10)
//查询numbers中第11条到20条的数据
//skip()用于跳过指定数量的数据 skip( (页码-1)*每页显示的条数 ).limit(每页显示的条数)
//MongoDB会自动调整limit()和skip()的位置
db.numbers.find().skip(10).limit(10)
db.numbers.find().limit(10).skip(10)
- find()查询文档时,默认情况是按照_id的值进行升序排列
- sort()可以用来指定文档的排序的规则,需要传递一个属性来指定排序规则,1表示升序,-1表示降序
db.users.find({}).sort({sale:1}) db.users.find({}).sort({sale:1,qq:-1}) //先指定sale的升序 再按qq的降序
- limit、skip、sort可以任意顺序的调用
- 查询时,我们可以在第二个参数的位置来设置查询结果的投影,设置为0就不显示,1为显示(设置了什么就只会显示什么,可以理解为筛选,_id 那一列默认都会有)
//只会查询所有的数据的 sale 那一列 还有 _id并显示出来 db.users.find({},{ sale:1 }) //只显示 sale, name 那两列,隐藏 _id 那一列 db.users.find({},{ sale: 1, _id: 0, name: 1 })
当需要在webstorm或vscode时编写mongoose时,需要先将mongoose模块引入。步骤如下:
使用Mongoose:
1、下载安装 在终端输入命令行:npm i mongoose
2、引入mongose模块
const mongoose = require('mongoose')
3、 连接mongoDB数据库- 端口号是默认的 (27017), 则可以省略不写
mongoose.connect('mongodb://数据库的ip地址:端口号/数据库名')
4、断开连接(一般不用)
mongoose.disconnect();
5、监听MongoDB数据库的连接状态
- 在momgoose对象中, 有一个属性叫 connnection 用来监视数据库的链接状态mongoose.connection.once("open", ()=>{}); 监听数据库连接成功的事件 mongoose.connection.once("close", ()=>{}); 监听数据库断开连接的事件
// 完整代码使用案例
// 1、导入 mongoose 模块
const mongoose = require('mongoose')
// 2、连接数据库并且监听
// mongoose.connect("mongodb://数据库ip地址:端口/数据库名称");
mongoose.connect('mongodb://localhost:27017/student',{ useNewUrlParser: true })
mongoose.connection.once("open", ()=>{
console.log('数据库连接成功……')
)
// 3、创建 Schema 约束对象
// 将mongoose.Schema重命名,为了方便后续代码可省略
const Schema = mongoose.Schema;
// const schema约束对象 = new Schema(约束的内容);
const stuSchema = new Schema({
name: String,
age: Number,
gender: {
type: String,
default: "female"
},
address: String
})
// 4、通过 Schema 创建 Model
// const 模型Model = mongoose.model( "mongodb 集合名", schema约束对象 );
// 如果集合名为单数,mongoose 会把它变成复数,如 student 创建之后的集合名是 students
const StuModel = mongoose.model( "student", stuSchema )
// 5、使用 模型Model,插入文档
// 模型model.create(文档document);
StuModel.create({
name: "孙悟空",
age: 18,
gender: "male",
address: "花果山"
},(err, docs) => {
if(!err){
console.log("插入成功" + docs)
}
})
Schema(约束对象) 支持的字段类型
类型 | 作用 |
---|---|
String | 定义字符串 |
Number | 定义数字 |
Date | 定义日期 |
Buffer | 定义二进制 |
Boolean | 定义布尔值 |
Mixed | 定义混合类型 |
ObjectId | 定义对象ID |
Array | 定义数组 |
有了 Model,我们就可以来对数据库进行增删改查
1. 添加
Model.create(doc,[callback]); //创建一个或多个对象
Model.createOne(doc, [callback]); //创建一个对象
Model.createMany(doc, [callback]); //创建多个对象
// doc是需要插入的一个文档对象,或一个文档对象的数组
// callback(err) 是回调函数,可以用来提示是否创建成功了
2. 查询
// 查询一个或多个文档,返回数组
Model.find(condition, [projection], [options], [callback]);
// 根据id查询一个文档
Model.findById(id, [projection], [callback]);
// 查询多个文档
Model.findMany(condition, [projection]. [callback]);
// 查询一个文档
Model.findOne(condition, [projection], [options], [callback]);
/*
-- condition 查询条件,必选参数
-- projection: 投影,即是否显示,可选参数
{name: 1, _id:0}: 1是显示,0是不显示 ,这里显示name, 不显示 _id
-- options: 查询的选项, skip是跳过,limit是限制 {skip: 3, limit:3},可选参数
-- callback: 回调函数,有两个参数(err, doc) err是错误类型, doc是文档,必选参数
*/
// 例
stuModel.find({}, (err, doc)=>{
if(!err){
console.log(doc);
}
});
stuModel.findById("6137839348ee37e25b1c1c74", (err, doc)=>{
if(!err){
console.log(doc);
}
});
stuModel.findOne({ name: "西施" }, { name: 1, _id: 0 }, (err, doc)=>{
if(!err){
console.log(doc);
}
});
3. 修改
Model.updateMany(condition, doc, [options], [callback]);
Model.updateOne(condition, doc, [options], [callback]);
/*
** Model.update() 已经不适用了
-- condition 修改的条件
-- doc 修改后的内容/需要修改的内容
需要配合修改操作符来使用:
$set 表示需要设置指定的属性
$unset 表示需要删除指定的属性
$push 表示给数组添加一个新元素,因为文档内也会有数组,数组便会有数组元素
$addToset 表示给数组添加一个新元素,和push的区别是,如果出现同名的数组元素,则不会再添加
$gt 大于
$gte 大于等于
$lt 小于
$lte 小于等于
$or [{条件一,条件二}] 表示或的意思,符合条件一或者条件二
$inc 表示自增,用在在原来数据的基础上对数据加减,可用于加薪减薪的操作
*/
// 例
stuModel.updateOne({name:"西施"}, {$set: {address: "北京"}}, (err)=>{
if(!err){
console.log('修改成功~');
}
});
4. 删除
// condition 条件 callback 回调函数
/*
** 删除语句在实际开发中用的少,一般数据库中的数据都不会删除,
** 所以删除的方法很少调用,一般会在数据中添加一个字段,来表示数据是否被删除
*/
Model.remove(condition, [callback]);
Model.deleteOne(condition, [callback]);
Model.deleteMany(condition, [callback]);
5. 统计
// 统计当前集合中符合条件的文档的数量
// condition 条件 callback 回调函数
Model.count(condition, [callback]);
// 通过 model 创建一个文档对象
const stuDoc = new StuModel({
name: "张三",
age: 40,
gender: "male",
address: "市中心"
})
// doc.save([options], [callback])
stuDoc.save((err, doc) => {
if(!err){
console.log("保存成功" + doc)
}
})
// 修改文档对象
// 方式一:doc.update([options], [callback])
// 方式二:doc.age = 18; doc.save();
stuDoc.update({$set:{ age: 28 }}, (err) => {
if(!err){
console.log("修改成功" )
}
})
// 删除文档对象
//doc.remove([callback])
stuDoc.remove((err) => {
if(!err){
console.log("大师兄再见" )
}
})
// 获取文档指定属性值
doc.get("name") === console.log(doc.name)
// 设置文档指定属性值
doc.set("name", "猪猪") === doc.name = "猪猪";
// 获取文档的_id属性值
console.log(doc.id)
// 转换成 JSON 对象
doc.toJSON()
// 将doc对象 转换成 普通JS对象, 转换后, 所有doc的属性和方法都不能使用了
doc.toObject()