Node.js学习——Node.js 操作mongoose

一、Node.js 操作mongoose进行增删改查

Mongoose 是在 node.js 异步环境下对 mongodb 进行便捷操作的对象模型工具。Mongoose 是 NodeJS 的驱动,不能作为其他语言的驱动。
官网:https://mongoosejs.com/

//1.引入mongoose,在这之前需要先安装:npm install mongoose --save
const mongoose = require('mongoose');

//2、建立连接  
// 如果没有密码connect中的内容就为: 'mongodb://127.0.0.1:27017/std'
mongoose.connect('mongodb://admin:123456@127.0.0.1:27017/std?authSource=admin', (err, doc) => {
    if (err) {
        return console.log(err);
    }
});

//3、操作admin表(集合)   定义一个Schema   Schema里面的对象和数据库表里面的字段需要一一对应

const AdminSchema = new mongoose.Schema({
    adminName: String,
    age: Number,
    gender: {                  // 指定默认参数,在新增时不添加这个字段就会默认添加
          type: String,
          default: 'male'
    }
});

//4、定义数据库模型  操作数据库

// model里面的第一个参数 要注意:1、首字母大写  2、要和数据库表(集合 )名称对应  这个模型会和模型名称相同的复数的数据库表建立连接

// var User=mongoose.model('Admin', AdminSchema);    // 默认会操作 admins表(集合)

const Admin = mongoose.model('Admin', AdminSchema, 'admin'); // 此时的第三个参数就是需要操作的admin表(集合),进行了代理,操作的就不是admins了

// 5、查询admin表的数据

// Admin.find({}, function (err, docs) {
//     if (err) {
//         console.log(err);
//         return;
//     }
//     console.log(docs);
// })

//6、增加数据

// 6.1实例化 Model     通过实例化User Molde 创建增加的数据

//6.2 实例.save()

// var ad = new Admin({
//     //实例化模型 传入增加的数据
//     adminName: '王二',
//     age: 20,
//     gender: 'male',
//     phone: '123456'      // 此处的字段phone没有出现在AdminSchema中,所有并不会增加到数据库中
// }); 
// ad.save((err,doc)=>{
//     if (err) {
//         return console.log(err);
//     }
//     console.log('新增数据成功');
// });

//7、修改数据

// Admin.updateOne(
//     {
//         "_id": "61b45aadcd170625962473d7"
//     }, 
//     {
//         "gender": "男"
//     },
//     function (err, doc) {
//         if (err) {
//             return console.log(err);
//         }
//         console.log(doc)
//     }
// )


// 8、删除数据
// Admin.deleteOne(
//     {
//         _id: '61a9cae3e123cfd055adbfc1'
//     }, 
//     function (err) {
//         if (err) {
//             console.log(err);
//             return;
//         }
//         // deleted at most one tank document 
//         console.log('删除成功');
//     }
// );

// 9、保存成功并查找

var addAdmin = new Admin({
    adminName: '小可',
    age: 20,
    gender: '女'
})

addAdmin.save((err,doc)=>{
    if (err) {
        return console.log(err);
    }
    Admin.find({},(err,doc)=>{
        if (err) {
            return console.log(err);
        }
        console.log(doc);
    })
})

注意 mongoose.model()中传入的参数中,
第一个参数:1、首字母大写 2、要和数据库表(集合 )名称对应 这个模型会和模型名称相同的复数的数据库表建立连接。
第二个参数:对应数据库表的schema。
第三个参数:就是对需要操作的表(集合)进行了代理,此时操作的数据库就是第三个参数中所代理的数据库,也可以不传,如果不传,操作的就是第一个参数的复数形式所指代的数据库。

二、 Node.js操作mongoose进行模块化

代码目录如下


代码目录

在module/db.js中进行连接数据库操作

//连接数据库
const mongoose = require('mongoose');

mongoose.connect('mongodb://admin:123456@127.0.0.1:27017/std?authSource=admin', (err, doc) => {
    if (err) {
        return console.log(err);
    }
});

module.exports = mongoose;

在module/admin.js中定义Schema并创建model

// 定义Schema并创建model
const mongoose = require('./db');

const AdminSchema = new mongoose.Schema({
    adminName: String,
    age: Number,
    gender: String,
    status: {
        type: Number,
        default: 1
    }
});

module.exports = mongoose.model('Admin', AdminSchema, 'admin');

在operateAdmin.js中操作admin

const Admin = require('./module/admin');

const add = new Admin({
    adminName: '大梦',
    age: 30,
    gender: '男',
})

add.save((err,doc)=>{
    if (err) {
        return console.log(err);
    }
    Admin.find({},(err,doc)=>{
        if (err) {
            return console.log(err);
        }
        console.log(doc);
    })
})

三、 Node.js操作mongoose自定义修饰符

修饰符一般用在创建Schema时

1. 预定义修饰符:

  • lowercase:将传入的内容转换为小写;
  • uppercase:将传入的内容转换为大写;
  • trim:将传入的字符串去掉首尾的空格;

2. Getters 与 Setters 自定义修饰符

  • set 修饰符在增加数据的 时候对数据进行格式化。
  • get修饰符(不建议使用)在实例获取数据的时候对数据进行格式化。

在module/admin.js中

...
const AdminSchema = new mongoose.Schema({
    adminName: {
        type:String,
        trime:true      //定义 mongoose模式修饰符 去掉空格
    },
    age: {
        type:Number,
        get(params){ // 基本不用
            return '年龄是:' + params
        }
    },
    gender: String,
    status: {
        type: Number,
        default: 1
    },
    blog: {
        type:String,
        set(params){ // set 用于修改存入数据库之前的数据内容
            // params就是存入到数据库中的值
            if(!params){
                return ''
            } else {
                if(params.indexOf('http://') !== 0 || params.indexOf('https://') !== 0){
                    return 'http://'+params;
                }
                return params;
            }
        }
    }
});
...

新建operateAdmin.js文件,其中

const Admin = require('./module/admin');

const add = new Admin({
    adminName: '    一眼万年   ',
    age: 30,
    gender: '男'
})

console.log(add.age); // 得到的是get自定义修饰符,并不会传入数据库中

add.blog = 'jianshu.com'  // 传入数据库中时会使用set自定义修饰符自动补全网站的http协议头

四、Node.js操作mongoose索引,静态方法和实例方法

  • mongoose 中除了使用MongDB底层创建索引的方式,也可以在定义 Schema 的时候指定创建索引。
  • mongoose的静态方法和实例方法也在创建Schema时定义。
    在module/admin.js中
...
const AdminSchema = new mongoose.Schema({
    adminName: {
        type: String,
        trime: true,
        // 普通索引 
        index: true
    },
    sn: {
        type: Number,
        // 唯一索引 
        unique: true
    },
   ...
});
...
//静态方法 
AdminSchema.statics.findBySn = function (sn,cb) {
    //通过 find方法获取 sn的数据    this关键字获取当前的model
    this.find({'sn':sn},(err,doc)=>{
        cb(doc)
    })
}
// 实例方法   (基本不用)
AdminSchema.methods.print = function () {
    console.log('这是一个实例方法');
    console.log(this.adminName);  // 此处的this是生成的Schema实例
}
...

调用静态方法和实例方法

const Admin = require('./module/admin');

// const add = new Admin({
//     adminName: '    一眼万年   ',
//     age: 30,
//     gender: '男',
//     sn:'123456781',
// })
// add.save()

// 调用静态方法
Admin.findBySn('123456781',function(err,docs){
    if(err){
        console.log(err);
        return;
    }
    console.log(docs)
})

// 调用实例方法
var user = new Admin({
    adminName: '赵六',
    sn:'123456781',
    age: 29
});
user.print()

五、Node.js操作mongoose数据校验

mongoose数据校验:用户通过mongoose给mongodb数据库增加数据的时候,对数据的合法性进行的验证;
mongoose里面定义Schema:字段类型,修饰符、默认参数 、数据校验都是为了数据库数据的一致性。

1. 校验参数

  • max: 用于 Number 类型数据,最大值
  • min: 用于 Number 类型数据,最小值
    以下适用于String类型数据
  • required: 表示这个数据必须传入
  • enum: 枚举类型,要求数据必须满足枚举值 enum: ['0', '1', '2']
  • match: 增加的数据必须符合 match(正则)的规则
  • maxlength:最大长度
  • minlength:最小长度

2. 自定义校验参器

validate: function(sn) {   // 自定义校验,如果通过验证返回true,如果没有通过就返回false
       return sn.length >= 10;
}

在module/admin.js中

...
var UserSchema=mongoose.Schema({
    name:{
        type:String,//指定类型
        trim:true,   //修饰符         
        required:true  //    
    },
    sn:{
        type:String,
        index:true,  //索引.
        set(val){  //自定义修饰符
            return val;
        },

        // maxlength:20,
        // minlength:10
        // match:/^sn(.*)/ ,
        validate: function(sn) {   // 自定义校验,如果通过验证返回true,如果没有通过就返回false
            return sn.length >= 10;
        }        
        
    },   
    age:{
        type:Number,
        min:0,    //用在number类型上面
        max:150
    },       
    status:{
        type:String, 
        default:'success', //默认值
        enum:['success','error']   //status的值必须在 对应的数组里面  注意枚举是用在String
    }
})
...

六、Node.js操作mongoose实现聚合管道aggregate

在module/db_order.js中

const mongoose = require('mongoose');

mongoose.connect('mongodb://admin:123456@127.0.0.1:27017/usp?authSource=admin', (err, doc) => {
    if (err) {
        return console.log(err);
    }
});

module.exports = mongoose;

在module/order.js中

const mongoose = require('./db_order')

const OrderSchema = new mongoose.Schema({
    order_id:String,
    uid:Number,
    trade_no:String,
    all_price:Number,
    all_num:Number  
})

module.exports = mongoose.model('Order', OrderSchema, 'order');

在module/order_item.js中

const mongoose = require('./db_order')

const OrderItemSchema = new mongoose.Schema({
    order_id:String,
    title:String,
    price:Number,
    num:Number  
})

module.exports = mongoose.model('Order_item', OrderItemSchema, 'order_item');

在operateAggregate.js中

//order表关联order_item
/*
    const OrderModel = require('./module/order');

    OrderModel.aggregate([
        {
            $lookup: {
                from: "order_item",
                localField: "order_id",
                foreignField: "order_id",
                as: "items"
            }
        },
        {
            $match:{"all_price":{$gte:90}}
        }
    ],function (err,doc) {
        if(err){        
            return console.log(err);
        }
        console.log(JSON.stringify(doc))
    })
*/

// order_item表关联order表

// 方法一:查询两个表
/*
    const OrderItemModel = require('./module/order_item');

    const OrderModel = require('./module/order');

    OrderItemModel.find({"_id":"61adfc90465893490e129d58"},function(err,docs){

        var order_item=JSON.parse(JSON.stringify(docs));

        var order_id=order_item[0].order_id;

        OrderModel.find({"order_id":order_id},function(err,order){

            order_item[0].order_info=order[0];

            console.log(order_item)
        })
    })
*/
// 方法二:使用关联方式

const OrderItemModel = require('./module/order_item');

const mongoose = require('mongoose');

OrderItemModel.aggregate([{
        $lookup: {
            from: "order",
            localField: "order_id",
            foreignField: "order_id",
            as: "order_info"
        }
    },
    {
        $match: {
            _id: mongoose.Types.ObjectId('61adfc90465893490e129d58')
        }
    }
], function (err, doc) {
    if (err) {

        console.log(err)
        return;
    }

    console.log(JSON.stringify(doc))
})
/*
[{
    "_id": "61adfc90465893490e129d58",
    "order_id": "2",
    "title": "酸奶",
    "price": 40,
    "num": 1,
    "order_info": [{
        "_id": "61adfbfa465893490e129d52",
        "order_id": "2",
        "uid": 7,
        "trade_no": "222",
        "all_price": 90,
        "all_num": 2
    }]
}]
*/

七、Node.js操作mongoose实现多表关联

在文件module/db_article.js中连接数据库

const mongoose = require('mongoose');

mongoose.connect('mongodb://admin:123456@127.0.0.1:27017/usp?authSource=admin', (err, doc) => {
    if (err) {
        return console.log(err);
    }
});

module.exports = mongoose;

在文件module/articlecate.js中创建articleCate表的model

const mongoose = require('./db_article')

const ArticleCateSchema = new mongoose.Schema({
    title: { type: String, unique: true },
    description: String,
    addtime:{
        type:Date       
    }
})

module.exports = mongoose.model('ArticleCate',ArticleCateSchema,'articleCate')

在文件module/articleauther.js中创建articleAuther表的model

const mongoose = require('./db_article')

const ArticleAutherSchema = new mongoose.Schema({
    username  : { type: String, unique: true },
    password:String,
    name:String,
    age:Number,
    sex:String,
    tel:Number,
    status:{
        type:Number,
        default:1
    }
})

module.exports = mongoose.model('ArticleAuther',ArticleAutherSchema,'articleAuther')

在文件module/article.js中创建article表的model

const mongoose = require('./db_article')
const Schema = mongoose.Schema

const ArticleSchema = new Schema({
    title:{ 
        
        type: String, unique: true 
    
    },
    cid : { 
        
        type: Schema.Types.ObjectId
    
    },   /*分类 id*/

    author_id:{        
        type: Schema.Types.ObjectId
    },   /*用户的id*/
    author_name:{        
        type:String      
    },
    descripton:String,   
    content   : String
})

module.exports = mongoose.model('Article',ArticleSchema,'article')

在operateMAggregation.js文件中增加数据和查询多表关联数据

const ArticleSchema = require('./module/article');

const ArticleAutherSchema = require('./module/articleauther');

const ArticleCateSchema = require('./module/articlecate');

// 增加数据

// const articleauther = new ArticleAutherSchema({
//     username: '大梦',
//     password:'5423451',
//     name:'梦幻',
//     age:28,
//     sex:'男',
//     tel:642345,
// })
// articleauther.save((err,doc)=>{
//     ArticleAutherSchema.find({},(err,articleauther)=>{
//         console.log(articleauther);
//     })
// })

// const articlecate = new ArticleCateSchema({
//     title:'国内新闻——某省',
//     description:'国内新闻——某省'
// })
// articlecate.save((err,doc)=>{
//     ArticleCateSchema.find({},(err,articlecate)=>{
//         console.log(articlecate);
//     })
// })

// const article = new ArticleSchema()
// article.title="这是一个国际新闻"
// article.cid='61ba8f0dd80ec05cf28f1454';
// article.author_id='61ba05a2eb6bd25ebb98316d';  
// article.author_name='大梦';
// article.descripton='这是一条国际新闻 此处省略18字';
// article.content='这是一条国际新闻,此处省略330字'
// article.save()

// 多个表关联查询
// 在两表关联的基础之上新增一个$lookup条件就可以实现多表关联

ArticleSchema.aggregate([{
        $lookup: {
            from: "articleCate",
            localField: "cid",
            foreignField: "_id",
            as: "cate"
        }
    },
    {
        $lookup: {
            from: "articleAuther",
            localField: "author_id",
            foreignField: "_id",
            as: "user"
        }
    }
], function (err, docs) {
    console.log(JSON.stringify(docs))
})
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,591评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,448评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,823评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,204评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,228评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,190评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,078评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,923评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,334评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,550评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,727评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,428评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,022评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,672评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,826评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,734评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,619评论 2 354

推荐阅读更多精彩内容