MongodDB学习笔记
? 在MongoDB中,数据库和集合都不需要我们手动创建,当我们创建文档时,如果文档所在的集合或数据库不存在,她会自动创建数据库和集合!
- 什么是数据库?
存储数据的仓库 - 为什么要有数据库?
首先数据是存储在内存里运行的,如果一断电的话,数据就会丢失,所以可以将数据存储到硬盘,但是硬盘没有联网,所以有了可以联网也可以存储数据的数据库。 - 数据库能做什么?
数据库可以存储数据,并且这些数据还可以连接网络,也就是和硬盘相比,可以不用将数据库到处带,就像是网盘。 - 数据库的服务器和客户端
值得注意的是数据库它也是分为服务器和客户端的
MongoDB的优点
- 可以快速开发web型应用,因为灵活,不用像关系型数据库一样需要建表
- MongoDB存储的是文档(document),文档内存储的是类似json的结构,所谓json就是字符串数组
MongoDB的数据库分类
- 数据库(database):用来存储集合的,而且数据库也有分大小。
- 集合(collection):集合类似于数组,用于存放文档的
- 文档(document): 文档是MongoDB数据库中最小的单位,我们要操作的目标就是文档。
基本指令
-
show dbs:显示当前所有数据库 show database:显示当前所有数据库 -
use 数据库名:进入到指定的数据库中(可以不存在) -
db:表示我们当前所处的数据库 -
show collections:显示我们数据库中所有的集合 -
开启服务器: net start MongoDB -
关闭服务器: net stop MongoDB -
打开客户端: mongo,在cmd窗口输入便可以连接上数据库
基本操作(CRUD)
增加
1.向数据库插入文档:
db..insert() 向集合中插入一个或多个文档
2.当我们向集合中插入文档时,如果没有给文档指定_id,则数据库会自动为文档添加_id,该属性用来作为文档的唯一标识 _id可以自己指定,如果我们自己指定了数据库就不会砸添加了,如果自己指定_id,也要确保它的唯一性
- db.collection.insertOne()
插入一个文档对象 db.collection.insertMany() 插入多个文档对象
use stus
db.stus.insert({name:"孙悟空",age:18,gender:"男"});
db.stus.insert({name:"猪八戒",age:28,gender:"男"});
db.stus.insert([
{name:"沙和尚",age:38,gender:"男"},
{name:"唐玄奘",age:18,gender:"男"}
]);
db.stus.insert({_id:"9527",name:"猪八戒",age:28,gender:"男"});
db.stus.find();
ObjectId()
查询
-
db..find() find()用来查询集合中所有符合条件的文档 ? find()可以接收一个对象作为条件参数 ? {}表示查询集合中所有的文档 ? {属性名:值} 查询属性是指定值的文档 ? find()返回的是一个数组 -
db..findOne() 用来查询集合中符合条件的第一个文档 findOne()返回的是一个文档对象 -
db..find().count() //length()也可以 查询所有结果的数量 ?
db.stus.find({_id:"9527"});
db.stus.find({name:"猪八戒",age:28});
db.stus.find({age:28});
db.stus.findOne({age:28}).name;
db.stus.find({}).count();
修改
- db..update(查询条件,新对象)
update()默认情况下会使新对象替换旧对象 如果需要修改指定的属性而不是替换,需要使用"修改操作符"来完成修改 $set 可以用来修改文档中的指定属性 $unset 可以用来删除文档中的指定属性 update()默认只会修改一个 - db..updateMany()
同时修改多个符合条件的文档 - db..updateOne()
修改一个符合条件的文档 - db..replaceOne()
替换一个文档
//替换
db.stus.update({name:"沙和尚"},{name:"沙悟净"});
db.stus.update(
{"_id":ObjectId("616d22861772e7380ca63339")},
{$set:{
age:38,
gender:"男",
address:"流沙河"
}}
);
db.stus.update(
{"_id":ObjectId("616d22861772e7380ca63339")},
{$unset:{
address:1
}}
);
//默认只能修改一个
db.stus.update(
{"name":"猪八戒"},
{
$set:{
address:"高老庄"
}
}
);
db.stus.update(
{"name":"猪八戒"},
{
$set:{
address:"福陵洞"
}
},
{multi:true}
);
db.stus.updateMany(
{"name":"猪八戒"},
{
$set:{
address:"云栈山"
}
}
);
db.stus.replaceOne(
{"name":"猪八戒"},
{
address:"云栈山"
}
);
db.stus.find()
删除
-
db.collection.remove(查询条件) remove()可以根据条件来删除文档,传递条件的方式和find()一样 remove()删除符合条件的所有文档(默认情况下会删除多个) 如果remove()第二个参数(justone)传递一个true,则只会删除一个 如果只传递一个空对象作为参数,则会删除集合中的所 -
db.collection.deleteOne() 同时删除一个符合条件的文档 -
db.collection.deleteMany() 删除多个符合条件的文档 -
db.collection.drop(); 删除集合 -
db.dropDatabase() 删除数据库 ? --一般数据库中的数据都不会删除,所以删除的方法很少调用 ? 一般会在数据中添加一个字段,来表示数据是否被删除
db.stus.find({});
db.stus.remove({_id:"9527"});
db.stus.remove({age:18});
db.stus.insert([{age:18},{age:18}]);
db.stus.remove({age:18},true);
//清空集合
db.stus.remove({});
show collections;
db.stus.drop();
db.stue.insert([
{
name:"蜘蛛精",
isDel:0
},
{
name:"沙和尚",
isDel:0
},
{
name:"唐僧",
isDel:0
}
]);
db.stue.updateOne({name:"唐僧"},{$set:{isDel:"1"}});
db.stue.find({isDel:0});
练习
//1.进入my_test数据库
use my_test
//2.向数据库的user集合中插入一个文档
db.users.insert({
username:"孙悟空"
});
//3.查询user集合中的文档
db.users.find();
//4.向数据库的user集合中插入一个文档
db.users.insertOne({
username:"沙悟净"
});
//5.查询数据库user集合中的文档
db.users.find();
//6.统计数据库user集合中的文档数量
db.users.find().count();
//7.查询数据库中user集合中username为孙悟空的文档
db.users.find({username:"孙悟空"});
//8.向数据库user集合中的username为孙悟空的文档,添加一个address属性,属性值为花果山
db.users.update({username:"孙悟空"},{$set:{address:"花果山"}});
//9.使用{username:"唐僧"} 替换 username 为沙悟净的文档
db.users.replaceOne({username:"沙悟净"},{username:"唐僧"});
//10.删除username为孙悟空的文档的address属性
db.users.update({username:"孙悟空"},{$unset:{address:1}});
//11.向username为孙悟空的文档中,添加一个hobby:{cities:["北京","上海","深圳"],movies:["sanguo","hero"]}
//MongoDB的文档的属性值也可以是一个文档,当一个文档的属性值是一个文档时,我们称这个文档叫做 内嵌文档
db.users.update({username:"孙悟空"},{$set:{hobby:{cities:["北京","上海","深圳"],movies:["sanguo","hero"]}}});
db.users.find();
//12.向username为唐僧的文档中,添加一个hobby:{movies:["A Chinese Odyssey","King of comedy"]
db.users.update({username:"唐僧"},{$set:{hobby:{movies:["A Chinese Odyssey","King of comedy"]}}});
//13.查询喜欢电影hero的文档
//MongoDB支持直接通过内嵌文档的属性进行查询,如果要查询内嵌文档则可以通过.的形式来匹配
//如果要通过内嵌文档来对文档进行查询,此事属性名必须使用引号
db.users.find({"hobby.movies":"hero"});
//14.向唐僧中添加一个新的电影Interstellar
//$push 用于向数组中添加一个新的元素
//$addToSet 向数组中添加一个新元素,如果数组中已经存在了该元素,则不会添加
db.users.update({username:"唐僧"},{$push:{"hobby.movies":"Interstellar"}});
db.users.update({username:"唐僧"},{$addToSet:{"hobby.movies":"Interstellar"}});
//15.删除喜欢北京的用户
db.users.remove({"hobby.cities":"北京"});
//16.删除user集合
db.users.remove({});
db.users.drop();
show dbs;
show collections
//17.向numbers中插入20000条数据 25.9s
for(var i=1 ; i<=20000;i++){
db.numbers.insert({num:i});
}
db.numbers.find();
db.numbers.remove({});
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}});
//20.查询numbers中num小于30的文档
db.numbers.find({num:{$lt: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条数据
//limit()设置显示数据的上限
db.numbers.find().limit(10);
//在开发时,我们绝对不会执行不带条件的查询
db.numbers.find();
//24.查看numbers集合中的第11条到20条数据
/*
分页 每页显示10条
1-10
11-20
21-30
...
skip((页码-1)*每页显示的条数).limit(每页显示的条数);
skip()用于跳过指定数量的数据
MongoDB会自动调整skip和limit的位置
*/
db.numbers.find().skip(10).limit(10);
//25.查看numbers集合中的第21条到30数据
db.numbers.find().skip(20).limit(10);
db.numbers.find().limit(10).skip(10);
文档之间的关系
- 一对一(one to one)
夫妻(一个丈夫 对应 一个妻子) 在MongoDB中可以通过内嵌文档的形式来体现出一对一的关系 - 一对多(one to many) / many to one
也可以通过内嵌文档来映射一对多的关系 - 多对多(many to many)
投影和排序
- 查询文档时,默认情况下是按照_id的值进行排列(升序)
- sort()可以用来指定文档的排序的规则,sort()需要传递一个对象来指定排序规则 1表示升序,-1表示降序
- limit skip sort 可以以任意的顺序进行调用
- 查询时,可以在第二个参数的位置来设置查询结果的投影
Mongoose
? Mongoose是一个对象文档模型(ODM)库,它对Node原生的MongoDB模块进行了进一步地优化封装,并提供了更多的功能。在大多数情况下,它被用来把结构化的模式应用到一个MongoDB集合,并提供了验证和类型转换等好处。
- mongoose是nodejs中的专门用于操作mongodb数据库的js库
- mongoose中的对象:
- Schema 模式对象(用于约束文档的结构)
- Model 模型对象(即mongodb中的集合)
- Document 文档对象(即mongodb中的文档)
mongoose的好处:
- 可以为文档创建一个模式结构(Schema)
- 可以对模型中的对象/文档进行验证
- 数据可以通过类型转换转换为对象模型
- 可以使用中间件来应用业务逻辑挂钩
- 比Node原生的MongoDB驱动更容易
Mongoose使用步骤
-
下载安装Mongoose npm i mongoose --save -
在项目中引入mongoose var mongoose = requir(“mongoose”); -
连接MongoDB数据库 const mongoose = require(‘mongoose’); mongoose.connect(‘mongodb://localhost/test’,{useMongoClient:true}); mongoose.connect(‘mongodb://数据库的ip地址:端口号/数据库名’); 如果端口号是默认端口号(27017)则可以省略不写 -
断开数据库连接(一般不需要调) mongoose.disconnect();
? MongoDB数据库,一般情况下,只需要连接一次,连接一次以后,除非项目停止服务器关闭,否则连接一般不会断开
-
监听MongoDB数据库的连接状态 ? 在mongoose对象中,有一个属性叫做connection,该对象表示的就是数据库连接通过监视该对象的状态,可以来监听数据库的连接与断开 -
数据库连接成功的事件 mongoose.connection.once(“open”,function(){}); -
数据库断开的事件 mongoose.connection.once(“close”,function(){});
Model创建步骤
const mongoose = require("mongoose");
mongoose.connect("mongodb://127.0.0.1/mongoose_test");
mongoose.connection.once("open",function(){
console.log("数据库连接成功~~~~");
});
将mongoose.Schema赋值给一个变量
const Schema = mongoose.Schema;
创建Schema(模式)对象
const stuSchema = new Schema({
id:Number,
name:String,
age:Number,
gender:{
type:String,
default:"female"
},
address:String
});
- 通过Schema来创建Model
- Model代表的是数据库的集合,通过Model才能对数据库进行
- mongoose.model(modelName, schema)
- modeName 就是要映射的集合名 mongoose会自动将集合名变成复数
let StuModel = mongoose.model("student",stuSchema);
向数据库中插入一个文档 StuModel.create(doc,{function(err){}});
StuModel.create({
id:1,
name:"至尊宝",
age:18,
gender:"男",
address:"五台山"
},function(err){
if(!err){
console.log("插入成功!!!");
}
});
插入(creat(doc(s),callback)):
Model.create(doc(s),[callback])
- 用来创建一个或多个文档并添加到数据库中
- 参数:
doc(s):可以是一个文档对象,也可以是一个文档对象的数组 callback:当操作完成后调用的回调函数
StuModel.create([
{
id:2,
name:"二当家",
age:28,
gender:"男",
address:"五台山"
},{
id:3,
name:"瞎子",
age:25,
gender:"男",
address:"五台山"
}
],function(err){
if(!err){
console.log(arguments[1]);
}
});
查询(find(conditions,[projection],[options],callback)):
? 通过find()查询的结果,返回的对象,就是Document,文档对象,Document对象是Model的实例。
- model.find(conditions,[projection],[options],callback)
查询所有符合条件的文档 总会返回一个数组 - model.findById(conditions,[projection],[options],callback)
根据文档的id属性查询文档 - model.findOne(conditions,[projection],[options],callback)
查询符合条件的第一个文档 总会返回一个具体的文档对象 - conditions:查询的条件
- projection:投影 需要获取到的字段
两种方式: { name: 1, _id: 0 } ‘name age -_id’ - options:查询选项 { skip: xx, limit: xx }
- callback 回调函数,查询结果会通过回调函数返回
回调函数必传,如果不传回调函数,压根儿不会查询
StuModel.find({},{name:1 , _id:0},function(err,docs){
if(!err){
console.log(docs);
}
});
StuModel.find({},"name age -_id",{skip:1,limit:1},function(err,docs){
if(!err){
console.log(docs);
}
});
StuModel.findOne({},function(err,doc){
if(!err){
console.log(doc);
}
});
StuModel.findById("616ec600fd4aa934b1b0ab55",function(err,doc){
if(!err){
console.log(doc);
console.log(doc instanceof StuModel);
}
});
StuModel.create([
{
id:2,
name:"二当家",
age:28,
gender:"男",
address:"五台山"
},{
id:3,
name:"瞎子",
age:25,
gender:"男",
address:"五台山"
}
],function(err){
if(!err){
console.log(arguments[1]);
}
});
修改(update(conditions,[doc],[options],callback))
- Model.update(conditions,[doc],[options],callback)
- Model.updateMany(conditions,[doc],[options],callback)
- Model.uodateOne(conditions,[doc],[options],callback)
- Model.replaceOne(conditions,[doc],[options],callback)
用来修改一个或多个文档 参数: conditions:查询的条件 doc:修改后的文档对象 options:配置参数 { multi:true } callback 回调函数
StuModel.updateOne({name:"瞎子"},{$set:{age:18}},function(err){
if(!err){
console.log("修改成功!!!");
}
});
删除(remove(conditions,[callback]))
- model.remove(conditions,[callback])
- model.deleteOne(conditions,[callback])
- model.deleteMany(conditions,[callback])
StuModel.remove({
name: "二当家"
}, function(err, data) {
if (!err) {
console.log("删除成功");}
});
统计文档的数量:model.count(conditions,callback)
StuModel.count({},function(err,count){
if(!err){
console.log(count);
}
});
Document
Document 和 集合中的文档一一对应,Document是Model的实例 通过Model查询到的结果都是Document Document方法: Model#save([options],[Fn])
let stu = new StuModel({
id:1,
name:"白晶晶",
age:18,
gender:"女",
address:"盘丝洞"
});
stu.save(function(err){
if(!err){
console.log("保存成功~~~");
}
});
StuModel.findOne({},function(err,doc){
if(!err){
doc.update({$set:{age:28}},function(err){
if(!err){
console.log("修改成功~~~");
}
});
doc.age=38;
doc.save();
console.log(doc._id);
}
});
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8bhPPnOc-1634658771857)(D:\HTML\mongoose\Document方法.png)]
Mongoose的模块化
- 定义一个模块,用来连接MongoDB数据库 tools/connect_mongo.js
const mongooes = require("mongoose");
mongooes.connect("mongodb://localhost/mongooes_test");
mongooes.connection.once("open", function () {
console.log("数据库连接成功~~~");
});
2.为每一个集合创建一个模型 models/student.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const stuSchema = new Schema({
id: Number,
name: String,
age: Number,
gender: {
type: String,
default: "female"
},
address: String
});
let StuModel = mongoose.model("student", stuSchema);
module.exports = StuModel;
3.在需要引入的文件index.js中引入数据库连接文件和创建模型的文件:
require("./tools/connect_mongo")
let StuModel = require("./models/student");
console.log(StuModel);
StuModel.find({},function(err , docs){
if(!err){
console.log(docs);
}
});
.connection.once(“open”, function () { console.log(“数据库连接成功~~~”); });
2.为每一个集合创建一个模型 models/student.js
```js
const mongoose = require("mongoose");
//将mongoose.Schema赋值给一个变量
const Schema = mongoose.Schema;
//创建Schema(模式)对象
const stuSchema = new Schema({
id: Number,
name: String,
age: Number,
gender: {
type: String,
default: "female"
},
address: String
});
let StuModel = mongoose.model("student", stuSchema);
module.exports = StuModel;
// exports.model = StuModel;
3.在需要引入的文件index.js中引入数据库连接文件和创建模型的文件:
require("./tools/connect_mongo")
let StuModel = require("./models/student");
console.log(StuModel);
StuModel.find({},function(err , docs){
if(!err){
console.log(docs);
}
});
|