MongoDB学习

本节课学习视频:https://www.bilibili.com/video/av21989676/?p=1

一、MongoDB入门

1数据库

 

 2数据库分类

 3MongoDB简介

4三个概念

 5下载MongoDB

https://www.mongodb.org/dl/win32

 

6安装MongoDB

 win32的

 7改变mongocb的存储路径和端口

 

 8mongodb的启动

 9MongoDB设置为系统服务

 

 10MongDB基本概念

11MongoDB基本指令

 

 12 MongoDB插入文档

/*
    向数据库插入文档
        db.<collection>.insert();
        - 向集合中插入一个或者多个文档
        - 当我们向集合中插入文档时,如果没有给文档制定_id属性,则数据库会自动为文档添加_id
            该属性用来作为文档的唯一标识
        - _id我们可以自己制定,如果我们指定了数据库就不会再添加了,如果自己指定_id也必须确保它的为唯一性
        
        db.collection.insertOne()
        - 插入一个文档对象  只能插入一个 只能传一个对象      v3.2
        db.collection.insertMany()
        - 插入多个文档对象  必须传入数组 只有一个对象也要传递数组 v3.2
*/
db.stus.insert({name:"猪八戒",age:28,gender:"男"});  
   
db.stus.insert([
    {name:"沙和尚",age:38,gender:"男"},
    {name:"白骨精",age:16,gender:"女"},
    {name:"蜘蛛精",age:14,gender:"女"}
]);
 
db.stus.insert({_id:"hello",name:"猪八戒",age:28,gender:"男"}); 

db.stus.find();    
    
ObjectId();   

 13MongoDB查询文档

/*
    查询
        db.collection.find(); 
        - find()用来查询集合中所有符合条件的文档
        - find()可以接收一个对象作为条件参数  传递空对象{}和什么也不传递代表查找所有的
                {}表示查询集合中所有的文档
                {字段名:值} 查询属性时指定值的文档  例如{_id:"hello"}
        - find()返回的是一个数组
                    
        db.collection.findOne();
        - 用来查询集合中符合条件的第一个文档
        - findOne()返回的时一个文档对象
        
        db.collection.find({}).count();
        - 查询所有结果的数量  
*/
db.stus.find({_id:"hello"});   
db.stus.find({age:16,name:"白骨精"});    
db.stus.find({age:28})[0];              //返回数组   querySelectorAll
db.stus.findOne({age:28}).name;         //返回对象  可以有属性  querySelector
    
db.stus.find({}).count();   

 14MongoDB修改文档

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

//  替换
db.stus.update({name:"沙和尚"},{age:28});

db.stus.update(
    {"_id" : ObjectId("5c78df625f97456182461c5e")},
    {$set:{
        gender:"男",
        address:"流沙河"
    }}
);

db.stus.update(
    {"_id" : ObjectId("5c78df625f97456182461c5e")},
    {$unset:{
      address:1
    }}
);

db.stus.updateMany(     // update默认只会改一个 updateMany会全都改
    {"name" : "猪八戒"},
    {
        $set:{
        address:"猪老庄"
        }
    }
);

db.stus.update(     // update默认只会改一个 updateMany会全都改
    {"name" : "猪八戒"},
    {
        $set:{
        address:"哈哈哈"
        }
     },
     {
         multi:true // 可以使update修改多个
     }
);

db.stus.find();

 15MongoDB删除文档

/*
    删除
        db.collection.remove()  删除一个或者多个 第二个单数传递true 则只会删除一个
            - 删除符合条件的所有的文档(默认情况下会删除多个)
                如果remove()第二个参数传递一个true 则只会删除一个
            - 如果只传递一个空对象作为参数,则会删除集合中的所有文档
        db.collection.deleteOne()
        db.collection.deleteMany()
            - remove() 可以根据条件来删除文档,传递的条件的方式和find()一样
            
        db.collection.drop()
            - 删除集合
        db.dropDatabase();
            - 删除数据库
            
            -一般数据库中的数据都不会删除,所以删除的方法很少调用
                一般会在数据中添加一个字段,来表示数据是否被删除
*/
db.stus.find({});

db.stus.remove({_id:"hello"});
db.stus.remove({age:28},true);  //带上true  只删除一个
db.stus.insert([
    {age:28},
    {age:28}
]);

//  清空集合(性能差)
db.stus.remove({});   //全部删除

show collections;

db.stus.drop();

show dbs;

db.dropDatabase();  // 一般不用

db.stus.insert([
    {
        name:"猪八戒",
        isDel:0
    },
    {
    name:"沙和尚",
        isDel:0
    },
    {
    name:"唐僧",
        isDel:0
    }
]);

db.stus.updateOne({name:"唐僧"},{$set:{isDel:1}});

db.stus.find({isDel:0});    //利用这用方式删除数据

 16MongDB练习

//  1.进入my_test数据库
use my_test;

//  2.向数据库的users集合中插入一个文档
db.users.insert({
    username:"sunwukong"
});
show dbs;show collections;
//  3.查询users集合中的文档
db.users.find();

//  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 为 zhubaojie的文档
db.users.replaceOne({username:"zhubajie"},{username:"tangseng"});

//  10.删除username为sunwukong文档的address属性
db.users.update({username:"sunwukong"},{$unset:{address:1}});


//  11.向username为sunwukong的文档中,添加一个hobby:{cities:["beijing","shanghai","shenzhen"],movies:["sanguo","hero"]}
//  mongoDB的文档的属性也可以是一个文档,当一个文档的属性值是一个文档时,我们称这个文档叫做 内嵌文档
db.users.update({username:"sunwukong"},{$set:{hobby:{cities:["beijing","shanghai","shenzhen"],movies:["sanguo","hero"]}}});
db.users.find();

//  12.向username为tangseng的文档中,添加一个hobby:{movies:["A Chinese Odyssey","King of Comedy"]}
db.users.update({username:"tangseng"},{$set:{hobby:{movies:["A Chinese Odyssey","King of Comedy"]}}});

//  13.查询喜欢电影hero的文档
//  MongeDB支持直接通过内嵌文档的属性进行查询,如果要查询内嵌文档则可以通过 . 的形式来匹配
//  如果是通过内嵌文档来对文档进行查询,此时属性名必须使用引号       username:"sunwukong" username中包含sunwukong
db.users.find({"hobby.movies":"hero"});

//  14.向tangseng中添加一个新的电影 Interstellar
//  $push 用于向数组中添加一个新的元素        不考虑元素重复问题
//  $addToSet 向数组中添加一个新元素       如果数组中已经存在了该元素,则不会添加
db.users.update({username:"tangseng"},{$push:{"hobby.movies":"Interstellar"}});
db.users.update({username:"tangseng"},{$addToSet:{"hobby.movies":"Interstellar"}});
db.users.find();

//  15.删除喜欢beijing的用户
db.users.remove({"hobby.cities":"beijing"});

//  16.删除user集合
db.users.remove({});
db.users.drop();

show dbs;

//  17. 向numbers中插入20000条数据
for(var i =1 ; i <= 20000 ; i ++){
    db.numbers.insert({num:1});
}

db.numbers.find();

db.numbers.remove({});

var arr = [];

for(var i = 1 ;i <= 20000; i++){
    arr.push({num:i});
}

db.numbers.insert(arr);

 17MongoDB练习

//  18.查询numbers中num为500的文档
db.numbers.find({num:500});
db.numbers.find({num:{$eq:500}});
//  19.查询numbers中num大于5000的文档
db.numbers.find({num:{$gt:500}});
db.numbers.find({num:{$gte:500}});  //大于等于

//  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条数据
db.numbers.find({num:{$lte:10}});

//  limit()设置显示数据的上限
db.numbers.find().limit(10);
//  在开发时候,我们绝对不会执行不带条件的查询
db.numbers.find();

//  24.查询numbers集合中的第11条到20条数据
/*
    分页 每页10条
    1-10        0
    11-20       10
    21-30       20
    。。。。
    
    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);

 18MongDB文档间的关系

/*
    文档之间的关系
        一对一(one to one)
           - 夫妻 (一个丈夫 对应 一个妻子)
           - 在MongoDB 可以通过内嵌文档的形式来天出一对一关系 
                
        一对多(one to many) / 多对一(many to one)
            -父母  -孩子
            用户 和 订单
            文章 和 评论
                也可以通过内嵌文档来映射一对多的关系
        
        多对多(many to many)
            分类  商品 
*/
    
db.wifeAndHusband.insert([
    {
        name:"黄蓉",
        husband:{
            name:"郭靖"
        }
    },{
        name:"潘金莲",
            husband:{
                name:"武大郎"
        }
    }
    
]);
    
db.wifeAndHusband.find();    
    
  

//  一对多  用户 users 和 订单 orders
db.users.insert([{
    username:"swk"
    },{
    username:"zbj"
}]);
db.users.find();
db.order.insert({
    list:["苹果","香蕉","大鸭梨"],
    user_id:ObjectId("5c7b6d73eaa1bbf36efb0c37")
});

db.order.insert({
    list:["西瓜","香蕉"],
    user_id:ObjectId("5c7b6d73eaa1bbf36efb0c37")
});

db.order.insert({
    list:["牛肉","漫画"],
    user_id:ObjectId("5c7b6d73eaa1bbf36efb0c38")
});

db.order.find();

//  查找用户swk的订单
var user_id = db.users.findOne({username:"swk"})._id;
db.order.find({user_id:user_id});

//  查找用户zbj的订单
var user_id = db.users.findOne({username:"zbj"})._id;
db.order.find({user_id:user_id});

//  多对多
db.teachers.insert([
    {name:"洪七公"},
    {name:"黄药师"},
    {name:"龟仙人"}
]);

db.stus.insert([
    {
    name:"郭靖",
    tech_ids:[ObjectId("5c7b712feaa1bbf36efb0c3d"),ObjectId("5c7b712feaa1bbf36efb0c3e")]
    },
    {
    name:"孙悟空",
    tech_ids:[
    ObjectId("5c7b712feaa1bbf36efb0c3d"),
    ObjectId("5c7b712feaa1bbf36efb0c3e"),
    ObjectId("5c7b712feaa1bbf36efb0c3f")],
    },
]);

db.teachers.find();

db.stus.find();

 19MongoDB练习3

//  26.将dept和emp集合导入到数据库中
//  https://www.bilibili.com/video/av21989676/?p=13
db.dept.find();
db.emp.find();

//  27.查询公司小于2000的员工
db.emp.find({sal:{$lt:2000}});

//  28.查询工资在1000-2000之间的员工  
db.emp.findb.emp.find({sal:{$lt:2000,$gt:1000}});

//  29.查询工资小于1000或大于2500的员工
db.emp.findb.emp.find({$or:[{sal:{$lt:1000}},{sal:{$gt:2500}}]});

//  30.查询财务部的所有员工 depno
db.dept.findOne({dname:"财务部"}).deptno;
var depno = db.dept.find({dname:"财务部"})[0].deptno;
db.emp.find({depno:depno});

//  31.查询销售部的所有员工
db.dept.findOne({dname:"销售部"}).deptno;
var depno = db.dept.find({dname:"销售部"})[0].deptno;
db.emp.find({depno:depno});

//  32.查询所有mgr是7698的员工
db.emp.find({mgr:7698});

//  33.为所有信息低于1000的员工增加工资400元
db.emp.updateMany({sal:{$lte:1000}},{$inc:{sal:400}});

 20 MongoDB的sort和投影

//  查询文档时,默认情况是按照_id的值进行排序(升序)
//  sort()可以用来制定文档的排序的规则,sort()需要传递一个对象来制定排序规则  1升序 2降序
//  limit skip sort 可以以任意的顺序进行调用
db.emp.find({}).sort({sal:1});  //  由小到大
db.emp.find({}).sort({sal:-1});  //  由大到小
db.emp.find({}).sort({sal:1,empno:-1}); //先按照sal升序 相同的再按照empno降序

//  在查询的时候,可以在第二个参数的位置来设置查询结果的投影
db.emp.find({},{ename:1,_id:0,sal:1}); //查询所有的对象   显示ename属性则设置为1  不显示_id属性则设置为0

 二、Mongoose

 1简介

 

2Mongoose的优点

 

3Mongoose新的对象

 

 4通过Mongoose连接MongoDB

5connection

 6mongoose代码

 https://mongoosejs.com/

/***
 * 1. 下载安装Mongoose
 *      npm i mongoose -save     
 * 
 * 2. 在项目中引入mongoose
 *      var mongoose = require("mongoose"); 
 * 
 * 3. 连接MongoDB数据库
 *      mongoose.connect('mongodb://localhost:27017/test', {useNewUrlParser: true});
 *      mongoose.connect('mongodb://数据库的ip地址:端口号/数据库名', {useNewUrlParser: true});
 *      如果端口号是默认端口号(27017),则可以省略不写
 *
 * 4.   断开数据库连接(一般不需要调用)
 *          MongoDB数据库,一般情况下,只需要连接一次,连接一次以后,除非项目停止服务器关闭,否则连接一般不会断开
 *          mongoose.disconnect()
 * 
 *      监听MongoDB数据库的连续状态
 *          在mongoose对象中,有一个属性叫connection,该对象表示的就是数据库连接
 *              通过坚挺该对象的状态,可以来监听数据库的连接与断开
 * 
 *          数据库连接成功的事件
 *          mongoose.connection.once("open",function(){});
 *          
 *          数据库断开的事件
 *          mongoose.connection.once("close",function(){});
 * 
 *  */ 

 // 使用
 // 引入
 const mongoose = require("mongoose");  
 // 连接数据库
 mongoose.connect('mongodb://localhost:27017/test', {useNewUrlParser: true});

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

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

 // 断开数据库连接
mongoose.disconnect();

 7Mongoose的Schema和Model

// 使用
// 引入
const mongoose = require('mongoose');
// 连接数据库
mongoose.connect('mongodb://localhost:27017/test', { useNewUrlParser: true });

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

//  创建Schema(模式)对象
//  将mongoose.Schema   赋值给一个变量
var Schema = mongoose.Schema;

var stuSchema = new Schema({
  name: String,
  age: Number,
  gender: {
    type:String,
    default:"female"  //默认是female
  },
  address: String
});

//  通过Schema来创建Model
//  Model掉膘的是数据库的集合,通过Model才能对数据库进行操作
//  mongoose.model(modelName, schema)
//  modelName 就是要映射的集合名  mongoose会自动将集合名变成复数
var StuModel = mongoose.model('Student', stuSchema);

//  向数据库中插入一个文档
//  StuModel.create(doc,function(){})
StuModel.create({
  name:"孙悟空",
  age:"18",
  gender:"male",
  address:"花果山"
},function(err){
  if(!err){
    console.log("插入成功");
  }
});

 

 8Mongoose的增删改查

 

// 使用
// 引入
const mongoose = require('mongoose');
// 连接数据库
mongoose.connect('mongodb://localhost:27017/test', { useNewUrlParser: true });

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

//  创建Schema(模式)对象
//  将mongoose.Schema   赋值给一个变量
var Schema = mongoose.Schema;

var stuSchema = new Schema({
  name: String,
  age: Number,
  gender: {
    type: String,
    default: 'female' //默认是female
  },
  address: String
});

//  通过Schema来创建Model
var StuModel = mongoose.model('Student', stuSchema);

/**
 *  Model的一些操作
 *      有了Model 我们就可以来对数据库进行增删改查的操作了
 *
 * 1. Model.create(doc(s),[option],[callback]);
 *      用来创建一个或多个文档并添加到数据库中
 *      参数:
 *          doc(s) 可以是一个文档对象,也可以是一个文档对象对象的数组
 *
 * 2. 查询的
 *    Model.find(conditions,[projection],[options],[callback]);
 *      查询所有符合条件的文档  总会返回一个数组
 *    Model.findById(id,[projection],[options],[callback]);
 *      根据文档的id属性来查询文档
 *    Model.findOne([conditions],[projection],[options],[callback]);
 *      查询符合条件的第一个文档    总会返回一个具体的文档对象
 *
 *      conditons   查询条件
 *      projection  投影
 *          两种方式
 *              { name:1,_id:0}
 *              "name -_id"
 *      options     查询选项( skip limit )
 *      callback    回调函数,查询结果会通过回调函数返回
 *                      回调函数必须传,如果不传回调函数,就不会查询
 */
//
//  创建的代码
StuModel.create([
    {
        name:"猪八戒",
        age:28,
        gender:"male",
        address:"高老庄"
    },{
        name:"唐僧",
        age:16,
        gender:"male",
        address:"女儿国"
    }
],function(err){
    if(!err){
       console.log("插入成功~~~");
       console.log(arguments);
    }
});

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

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

// //  查询      name是唐僧的   设置投影
StuModel.find({name:"唐僧"},{name:1,_id:0},function(err,docs){
    if(!err){
        console.log(docs);
        console.log(docs[0].name);
    }
});
// //              name是唐僧的   设置投影
StuModel.find({name:"唐僧"},"name age -_id",function(err,docs){
    if(!err){
        console.log(docs);
        console.log(docs[0].name);
    }
});

//                设置投影       跳过3个
StuModel.find({},"name age -_id",{ skip:3 },function(err,docs){
    if(!err){
        console.log(docs);
        console.log(docs[0].name);
    }
});

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

StuModel.findById("5c7c9241c90a601ad87c8571",function(err,doc){
    if(!err){
        console.log(doc);
        console.log(doc.name);
        //  通过find()查询的结果,返回的对象,就是Document  文档对象
        //  Document 对象是Model的实例
        console.log( doc instanceof StuModel );
    }
});

/**
 * 3. 修改
 *      Model.update( conditions,doc,[options],[callback] )
 *      Model.updateMany( conditions,doc,[options],[callback] )
 *      Model.updateOne( conditions,doc,[options],[callback] )
 *          用来修改一个或者多个文档
 *          参数:
 *              conditions:查询条件
 *              doc 修改后的对象
 *              options 配置参数
 *              callback    回调函数
 *
 *      Model.replaceOne( conditions,doc,[options],[callback] )
 *
 */

//  修改唐僧的年龄为20
StuModel.updateOne({name:"唐僧"},{$set:{age:20}},function(err){
    if( !err ){
        console.log("修改成功");
    }
});

/**
 *  4. 删除 remove
 *      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);
      }
});

 9Mongoose的Document方法

// 使用
// 引入
const mongoose = require('mongoose');
// 连接数据库
mongoose.connect('mongodb://localhost:27017/test', { useNewUrlParser: true });

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

//  创建Schema(模式)对象
//  将mongoose.Schema   赋值给一个变量
var Schema = mongoose.Schema;

var stuSchema = new Schema({
  name: String,
  age: Number,
  gender: {
    type: String,
    default: 'female' //默认是female
  },
  address: String
});

//  通过Schema来创建Model
var StuModel = mongoose.model('Student', stuSchema);

/**
 *  Document 和 集合 中的 文档一一对应,Document是Model的实例
 *      通过Model查询到结果都是Document
 */

// 创建一个 Document
var stu = new StuModel({
  name: '奔波霸',
  age: 48,
  gender: 'male',
  address: '碧波潭'
});

console.log(stu);

/**
 *  通过调用文档模型
 *  document的方法
 *      Model#save([options],[fn])
 */
stu.save(function(err){
    if(!err){
        console.log("保存成功~~~");
    }
});

StuModel.findOne({}, function(err, doc) {
  if (!err) {
    /**
     * update(update,[options],[callback])
     *      修改对象
     * remove([callback])
     *      删除对象
     */
    //  第二种修改方法
    console.log(doc);
    doc.update({$set:{age:28}},function(err){
        if(!err){
            console.log( "修改成功~~" );
        }
    });
    //第三种修改方法
    doc.age = 22;
    doc.save();
    console.log("修改了");

    //  第二种删除的方法
    doc.remove(function(err){
        if(!err){
            console.log("大师兄再见")
        }
    });

    /**
     *  get(name)
     *      获取文档中的制定属性值
     *  set(name,value)
     *      设置文档的指定的属性值
     *  id
     *      获取文档的_id属性
     * toJSON()
     *      转换为一个json对象
     * toObject()
     *      将Document对象转换为一个普通的js对象
     *          转换为普通的js对象以后,注意所有的Document对象的方法或属性都不能使用了
     */

    console.log(doc.get("age"));
    console.log(doc.age);

    doc.set("name","猪小小");   //没有save 所以数据库没影响
    doc.name = "猪小小";
    console.log(doc);

    console.log(doc.id);
    console.log(doc._id);

    console.log(doc.toJSON());
    console.log(doc.toObject);

    doc = doc.toObject();
    //  删除地址属性
    delete doc.address;
    console.log(doc._id);
    console.log(doc.address);
  }
});

 10Mongoose

 

conn_Mongo.js

/**
 *  定义一个模块,用来连接MongDB数据库
 */

 // 使用
// 引入
const mongoose = require('mongoose');
// 连接数据库
mongoose.connect('mongodb://localhost:27017/test', { useNewUrlParser: true });

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

student.js

/**
 *  用来定义Strdent的模型
 */

 var mongoose = require("mongoose");
//  创建Schema(模式)对象
//  将mongoose.Schema   赋值给一个变量
var Schema = mongoose.Schema;

var stuSchema = new Schema({
  name: String,
  age: Number,
  gender: {
    type: String,
    default: 'female' //默认是female
  },
  address: String
});

//  通过Schema来创建Model
var StuModel = mongoose.model('Student', stuSchema);

module.exports = StuModel;

E05_index.js

require("./tools/conn_Mongo.js");

var Student = require("./models/student.js");

Student.find({},function(err,docs){
    if( !err ){
        console.log(docs);
    }
});

未完待续

原文地址:https://www.cnblogs.com/NightTiger/p/10432149.html