mongodb总结

一、基本概念

mongodb是一种非关系型数据库(No SQL),也可以称为文档数据库,键值对数据库,mongodb数据模型是面向文档的,所谓文档即是类似json的结构,可以理解为mongodb存的就是json。结构关系是数据库中可以存放集合,在集合中可以存放文档,文档也是mongodb数据库的最小单位。需要注意的是在mongodb中数据库和集合都不需要手动创建,当我们创建文档时,如果文档所在的集合和数据库不存在,会自动创建数据库和集合。
在这里插入图片描述
启动mongodb服务器

在C盘下创建data文件夹,在文件夹中创建db文件夹,这个文件夹是mongodb默认是数据存放文件夹,cmd输入命令mongod,如果安装的32位mongodb,第一次启动命令是mongod --storageEngine=mmapv1,之后启动直接mongod即可。
在这里插入图片描述
启动mongodb时指定数据存放路径和端口,注意端口最大别超过65535

mongod --dbpath 数据库路径 --port 指定的端口

再打开一个命令行窗口,输入mongo,以下表示mongodb客户端启动成功
在这里插入图片描述
如果安装的mongodb版本小于5版本需要为mongodb设置为系统服务,实现在后台启动,不需要每次手动启动mongodb服务器。

mongodb一些简单命令

show dbs 或者  show databases  --查看所有的数据库
use  数据库名称                 --表示进入(使用)指定数据库
db                            --查看当前所在的数据库
show collections              --查看当前数据库中所有的集合

mongodb插入数据操作

--向数据库中插入文档,可以插入一个或多个文档  
    db.<collection>.insert(doc)
    例:向test数据库中的,stus集合中插入一个新的学生对象
    db.stus.insert ({"name" :"孙悟空","age":18,"gender":"男"})
--向集合中插入多个对象
    db.stus.insert ([
        {"name" :"张三","age":13,"gender":"男"},
        {"name" :"李四","age":15,"gender":"男"},
        {"name" :"王五","age":16,"gender":"男"}
])
--注意:如果当我们向集合中插入文档时,如果没有给文档指定_id属性,则数据库会自动为文档添加_id,该属性作为该文档的唯一标识,_id也可以自己指定,如果自己指定也需要确保唯一性
    --db.stus.insert ({"_id":"10001","name" :"孙悟空","age":18,"gender":"男"})
    --db.stus.insertOne()向集合中插入一个文档,只能是一个,mongodb3.2版本加入的方法
    --db.stus.insertMany()向集合中插入多个文档,只能是多个,mongodb3.2版本加入的方法
--$push向数组中添加一个新的元素,如果数组中已经存在该元素则继续添加
--$addToSet向数组中添加一个新元素,如果数组中已经存在该元素则不继续添加

mongodb查询数据操作

--查询当前集合中所有符合条件的文档
--find中参数可以接收一个对象,这个对象就是查询的条件,find返回的是一个数组
    db.<collection>.find()
    例:db.stus.find()
    例:db.stu.find("_id":"hello");
    例:db.stu.find("age":16,"name":"王五");查询姓名是王五年龄为16的数据
    例:db.stu.find("age":15)[0];查询数组中的一个文档对象
    例:db.stu.find({}).count();查询数组中有几个文档对象,count()统计数量
    例:db.stu.find({}).length();查询数组中有几个文档对象,length()统计数量
--查询集合中符合条件的第一个文档,如果有多个相同的文档只取第一个,findOne返回的是一个文档对象
    db.stu.findOne("_id":"hello");
    db.stu.findOne("_id":"hello").name;查询id为hello文档对象的姓名
注意查询文档时默认是按照_id的值进行排序(升序),可以通过sort()指定排序规则
例如:db.emp.find({}).sort({"sal":1,"empno":-1});先按照薪资进行升序排序如果薪资一样再按照empno降序排序,1表示升序,-1表示降序
注意:limit,sort,skip可以任意顺序调用
注意:在查询时,可以在第二个参数位置来设置查询结果的投影
db.emp.find({},{"ename":1});表示只查询ename属性,但是_id也会查出来   1表示显示,0表示不显示
db.emp.find({},{"ename":1,"_id":0});表示只查询ename属性,_id不会显示,只会显示ename属性

mongodb修改数据操作

--修改db.<collection>.update(查询条件,修改新对象),注意update默认会使用新对象去替换旧对象,注意如果集合中有多个相同的文档对象update只会修改一个文档对象
--update()是updateOne()和updateMany()综合,update()既可以修改一个也可以修改多个文档
    例:db.stus.update({"name":"李四"},{"age":99})表示将文档为李四的年龄修改为99
    --修改结果{"age":15}
--如果需要修改指定的属性而不是替换,需要使用修改操作符来完成修改
    例:db.stus.update({"name":"王五"},{$set:{"age":66}})表示将姓名为王五的文档对象年龄修改
    --修改结果{"name" :"王五","age":66,"gender":"男"}
--删除文档某个字段属性$unset,删除1表示删除一个属性值,不需要指定具体删除属性值
    例:db.stus.update({"name":"王五"},{$unset:{"gender":1}})表示删除姓名为王五的文档对象的gender属性和值
    --修改结果{"name" :"王五","age":66}
--db.<collection>.update()也可以修改多个文档
    例:db.stus.update({"name":"王五"},{$set:{"age":66}},{multi:true})如果有两个王五都会修改年龄为66
--db.<collection>.updateOne()修改一个符合条件的文档
--db.<collection>.updateMany()同时修改多个符合条件的文档
    例:db.stus.updateMany({"name":"王五"},{$set:{"age":66}})如果有两个王五都会修改 
--db.<collection>.replaceOne()替换一个文档

mongodb删除数据操作

--删除文档
db.collection.remove(); --删除符合条件的全部数据,传递的条件和find()一致,默认情况下有几个删几个,如果第二个参数传递true,则只会删除一个
db.collection.deleteOne();
db.collection.deleteMany();
例:db.stu.remove({"age":18});删除年龄为18的文档对象,注意如果存在多个年龄为18的文档对象,remove都会删除
例:db.stu.remove({});删除全部文档(性能比较差)

--删除集合  注意如果该集合为数据库中唯一的集合,删除集合后数据库就没了
db.collection.drop();
--删除数据库
db.dropDatabase();
--删除操作一般不建议真的删除,可以在数据中添加一个字段,表示(是否删除)逻辑删除  查询时查询条件为没删除的数据

mongodb练习

//1.进入my_test数据库
use my_test;
//2.向数据库的users集合中插入一个文档
db.users.insert({"username":"sunwukong"});
//4.向数据库的users集合中插入一个文档
db.users.insert({"username":"zhubajie"});
//5.查询数据库users集合中的文档
db.users.find({});
//6.统计数据库users集合中的文档数量
db.users.find().count();
//7.查询数据库users集合中username为sunwukong的文档
db.users.find({"username":"sunwukong"});
//8.向数据库users集合中的username为sunwukong的文档,添加一个address属性,属性值为huaguoshan
db.users.update({"username":"sunwukong"},{$set:{"address":"huaguoshan"}});
//9.使用{username : tangseng"}替换username 为zhubajie的文档
db.users.replaceOne({"username":"zhubajie"},{"username":"tangseng"});
//10.删除usernamne为sunwukong的文档的address属性
db.users.update({"username":"sunwukong"},{$unset:{"address":1}});
//11.向username为sunwukong的文档中,添加一个hobby:{cities:["beijing","shanghai","shenzhen"],[movies:["sanguo","hero"]}
db.users.update({"username":"sunwukong"},{$set:{"hobby":{cities:["beijing","shanghai","shenzhen"],[movies:["sanguo","hero"]}}});
//12.向username为tangseng的文档中,添加一个hobby:{movies: ["Aa chinese 0dyssey" , "King of comedy"]}
db.users.update({"username":"tangseng"},{$set:{"hobby":{movies:["Aa chinese 0dyssey","King of comedy"]}}});
//13.查询喜欢电影hero的文档
db.users.find({"hobby.movies":"hero"});
//14.向tangseng中添加一个新的电影Interstellar
db.users.update({"username":"tangseng"},{$push:{"hobby.movies":"Interstellar"}});
//15.删除喜欢beijing的用户
db.users.remove({"hobby.cities":"beijing"});
//16.删除users集合
db.users.remove({});
db.users.drop();
//17.向numbers中插入20000条数据
--方法1 效率较低
for(var i=1;i<=20000:i++){
    db.numbers.insert({"num":i});
}
--方法2 
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:500}});   $gt大于
db.numbers.find({"num":{$gte:500}});  $gte大于等于  $lt小于  $lte小于等于  $eq等于  $ne不等于
//21.查询numbers中num大于40小于50的文档
db.numbers.find({"num":{$gt:40,$lt:50}});
//23.查看numbers集合中的前10条数据   limit指定查询的上限值通常用于分页操作,limit中的参数是指每页显示的条数 
//skip((页码一1)大每页显示的条数).limit(每页显示的条数);
db.numbers.find().limit(10);
//25.查看numbers集合中的第21条到30条数据  skip()用于跳过指定数量的数据    MongoDB会自动词整skip和limit的位置 谁写前不影响
db.numbers.find().skip(20).limit (10);
//29.查询工资小于1000或大于2500的员工
db.emp.find({ $or: [{isal : {$1t:1000}} , {sal:{$gt:2500}}]});
//30.查询财务部的所有员工
var depno = db.dept.findone ({ dname : "财务部"} ).deptno;
db.emp.find ({ depno: depno }) ;
//33.为所有薪资低于1000的员工增加工资400元
db.emp.updateMany ({ sal: {$1te: 1000}} , {$inc:{ sal : 400}});   $inc表示自增,如果自减则自增一个负数
db.emp.find ()

文档之间的关系

一对一( one to one):可以通过内嵌文档的形式来体现出一对一的关系

db.WifeAndHusband.insert([
    {
        wife:"黄蓉",
        husband:{
            name:"郭靖"
        }
    },
    {
        wife:"潘金莲",
        husband:{
            name:"武大郎"
        }
    }
])

一对多( one to many)/多对一(many to one):父母和孩子、用户和订单、文章和评论,也可以通过内嵌文档的方式来映射一对多的关系(将1的那个属性设置为多的里面的字段)

db.order.insert({
    list:["watermelor"],
    user_id:ObjectId("5f87b1deda684b252c2fc7a5")
})

var user_id = db.users.findOne({username:"swk"})._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")
        ]
    }
])

Mongoose

简介
之前我们都是通过shell来完成对数据库的各种操作的,在开发中大部分时候我们都需要通过程序来完成对数据库的操作。
而Mongoose就是一个让我们可以通过Node来操作MongoDB的模块。

Mongoose是一个对象文档模型(ODM)库,它对Node原生的MongoDB模块进行了进一步的优化封装,并提供了更多的功能。
在大多数情况下,它被用来把结构化的模式应用到一个MongoDB集合,并提供了验证和类型转换等好处

mongoose的好处
可以为文档创建一个模式结构(Schema)

    可以对模型中的对象/文档进行验证

    数据可以通过类型转换转换为对象模型

    可以使用中间件来应用业务逻辑挂钩

    比Node原生的MongoDB驱动更容易
在webstorm中使用mongoose的方法
1.下载安装Mongoose,安装并添加到依赖
    npm i mongoose --save
2.在项目中引入mongoose
    var mongoose = require ( "mongoose" ) ;
3.连接MongoDB数据库  如果端口号是默认端口号(27017)则可以省略不写
    mongoose.connect ( 'mongodb://数据库的ip地址:端口号/数据库名',{ useMongoClient: true});
4.断开数据库连接(一般不需要调用):MongoDB数据库,一般情况下,只需要连接一次,连接一次以后,除非项目停止服务器关闭,否则连接一般不会断开
    mongoose.disconnect ()
监听MongoDB数据库的连接状态
    -在mongoose对象中,有一个属性叫做connection,该对象表示的就是数据库连接通过监视该对象的状态,可以来监听数据库的连接与断开
        mongoose.connction. once ( "open" ,function() {});数据库连接成功的事件
        mongoose.connction.once("close" ,function() {});数据库连接断开的事件
-------------------------
//引入
var mongoose = require ( "mongoose" );
//连接数据库
mongoose.connect ( "mongodb://127.0.0.1/mongoose_test" , { useMongoClient: true}) ;

mongoose.connection.once ( "open" ,function () {
    console.log("数据库连接成功~~~" ) ;
});

mongoose.connection.once ( "close" , function() {
    console.log("数据库连接已经断开~~~" );
});

//断开数据库连接
mongoose.disconnect();
-----------------------
//将mongoose.schema赋值给一个变量var schema = mongoose.schema;
//创建schema(模式)对象
var stuSchema = new schema ({
    name:String,
    age:Number,
    gender:{
        type:String,
        default:"female"
},
    address:String
});
//通过schema来创建Model
//Model代表的是数据库中的集合,通过Model才能对数据库进行操作 
// mongoose.model (modelName, schema ) :
//modelName就是要映射的集合名 mongoose会自动将集合名变成复数
//表示我要创建一个模型对象,这个模型对象和数据库中student集合进行映射,然后用stuSchema这个约束对模型进行约束
var StuModel = mongoose.model ("student" , stuSchema )  
//向数据库中插入一个文档
//StuModel.create(doc, function (err){});
StuModel.create( {
    name:"孙悟空",
    age:18,
    gender:"male",
    address:"花果山"
},function(err){
    if (!err) {
        console.log("插入成功~~~");
    }
});
/*
有了Model,我们就可以来对数据库进行增删改查的操作了
Model.create(doc(s),[callback])
用来创建一个或多个文档并添加到数据库中
    参数:
    doc(s):可以是一个文档对象,也可以是一个文档对象的数组
    callback:当操作完成以后调用的回调函数
*/
//插入
StuModel.create ([
    {
        name:"猪八戒",
        age:28,
        gender:"male",
        address:"高老庄"
    },
    {
        name:"唐僧",
        age:60,
        gender:"male",
        address:"女儿国"
    }
] ,function (err) {
    if (!err) {
        console.log("插入成功~~~")l
    }
});
/*
--查询
    -查询所有符合条件的文档:Model.find (conditions,[projection], [options],[callback]) 无论查不查到都返回一个数组,没有返回[]
    -根据文档的id属性查询文档:Model.findById (id,[projection] , [options], [callback])  总会返回一个具体的文档对象
    -查询符合条件的第一个文档:Model.findone ( [conditions],[projection], [options],[callback])  总会返回一个具体的文档对象
        conditions查询的条件projection投影
            -两种方式
                { name: 1,_id: 0 }
                "name - id"
        options查询选项( skip limit)
        callback回调函数,查询结果会通过回调函数返回,回调函数必须传,如果不传回调函数,压根不会查询
*/
StuModel.find ( { name: "唐僧" }, function (err , docs){//查询唐僧的文档
    if (!err){
        console.log(docs) ;
    }
});

StuModel.find ( { name: "唐僧" }, function (err , docs){//查询唐僧的name属性
    if (!err){
        console.log(docs[0].name) ;
    }
});

StuModel.find ( {}, function (err , docs){//查询所有文档的name属性
    if (!err){
        console.log(docs[0].name) ;
    }
});

StuModel.find ( {},{name:1 , _id:0}, function (err , docs){//只显示name字段,_id不显示
    if (!err){
        console.log(docs[0].name) ;
    }
});


StuModel.find ( {},"name -_id", function (err , docs){//只显示name字段,_id不显示
    if (!err){
        console.log(docs[0].name) ;
    }
});

StuModel.find ( {},"name -_id",{skip:3 ,limit:1}, function (err , docs){//skip跳过三条 limit只取1条
    if (!err){
        console.log(docs[0].name) ;
    }
});

StuModel.findOne ( {}, function (err , doc){
    if (!err){
        console.log(doc) ;
    }
});

StuModel.findById ("59c4c3cf4e5483191467d392" , function (err , doc) {
    if ( !err){
    //通过find ()查询的结果,返回的对象,就是Document文档对象
    //Document对象是Model的实例
        console.log (doc instanceof StuModel);//true
        console.log (doc) ;
    }
});
/*
修改
    Model.update (conditions,doc,[options],[callback])
    Model.updateMany(conditions,doc,[options],[callback])
    Model.updateone(conditions,doc,[options],[callback])
    -以上方法用来修改一个或多个文档
    -参数:
    conditions查询条件
    doc修改后的对象
    options配置参数
    callback回调函数
*/
StuModel.updateOne({name: "唐僧"},{ $set: { age:20} },function(err){
    if (!err) {
        console.log("修改成功");
    }
});
/*
删除
Model.remove(conditions,[callback] )
Model.deleteone(conditions,[callback])
Model.deleteMany(conditions,[callback])
*/
StuModel.remove({ name : "白骨精"},function (err) {
    if (!err){
        console.log("删除成功~~" );
    }
});
/*
Model.count(conditions,[callback])
-统计文档的数量
*/
StuModel.count({},function (err , count) {
    if (!err){
        console.log(count);
    }
});

/*
Document和集合中的文档一一对应﹐Document是Model的实例
通过Model查询到结果都是Document
Document的方法
    equals(doc)
    id
    get(path,[type])
    set(path,value,[type])
    update(update,[options],[callback])  注意这个修改不需要条件,因为就是此文档调用的方法,就是改本文档
    save([callback])
    remove([callback]) 删除该文档对象
    isNew:是不是一个新的文档
    isInit(path)
    toJSON():转换为JSON对象
    toObject():将Document对象转化为普通的JSON对象 转换为普通的json对象以后,注意所有的Document对象的方法或属性都不能使用了
*/
//创建一个Document
var stu = new StuModel ({
    name:"奔波霸"age:48,
    gender:"male",
    address:"碧波潭"
});
stu.save(function (err) {
    if (!err){
        console.log ("保存成功~~~");
    }
});

//update
    //方法1
    doc.update({$set: {age: 28}} ,function (err) {
        if ( !err) {
            console.log ( "修改成功~~~" ) ;
        }
    });
    //方法2
    doc.age=22;
    doc.save();
/*
get (name)  获取文档中的指定属性值
    console.log(doc.get("age"));
    console.log (doc.age);
set ()   设置文档中的指定属性值
    方法1
        doc.set("name","猪猪侠");
        doc.save();
    方法2
        doc.name="哈哈";
id:获取文档的id
    console.log(doc._id);或者console.log(doc.id)
*/
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值