美文网首页
mongodb笔记

mongodb笔记

作者: Scincyc | 来源:发表于2020-08-16 09:17 被阅读0次

    1.数据库概述及环境搭建

    1.1 数据库作用

    • 动态网站中的数据都是存储在数据库中的
    • 数据库可以用来持久存储客户端通过表单收集的用户信息
    • 数据库软件本身可以对数据进行高效的管理
    http://www.czxy.com/article?id=1
    http://www.czxy.com/article?id=2
    

    1.2 什么是数据库

    数据库即存储数据的仓库,可以将数据进行有序的分门别类的存储。它是独立于语言之外的软件,可以通过API去操作它
    常见的数据库软件有:mysql、mongoDB、oracle

    1.3 MongoDB下载安装

    下载地址:https://www.mongodb.com/download-center/community

    1.4 MongoDB Compass

    MongoDB可视化操作软件,是使用图形界面操作数据库的一种方式

    下载地址:https://www.mongodb.com/try/download/compass

    1.5 数据库相关概念

    在一个数据库软件中可以包含多个数据仓库,在每个数据仓库中可以包含多个数据集合,每个数据集合中可以包含多条文档(具体的数据)

    术语 解释说明
    database 数据库,mongoDB数据库软件中可以建立多个数据库
    collection 集合,一组数据的集合,可以理解为JavaScript中的数组
    document 文档,一条具体的数据,可以理解为JavaScript中的对象
    field 字段,文档中的属性名称,可以理解为JavaScript中的对象属性

    1.6 Mongoose第三方包

    使用Node.js操作MongoDB数据库需要依赖Node.js第三方包mongoose
    使用npm install mongoose命令下载

    1.7 启动MongoDB

    在命令行工具中运行net start mongoDB即可启动MongoDB,否则MongoDB将无法连接

    另外一种,创建mongo.conf文件写入数据库相关信息,在mongo.conf路径下,运行./mongod -f mongo.conf 或者

    mongod.exe --config=mongo.conf
    

    之后,打开MongoDB compass图形界面操作

    1.8 数据库连接

    使用mongoose提供的connect方法即可连接数据库

     const mongoose = require('mongoose');
    //mongoose.connect('mongodb://localhost/playground')// 使用mongodb协议 27017是数据库的默认端口,可不写
    mongoose.connect('mongodb://localhost/db_demo', { useNewUrlParser: true ,useUnifiedTopology: true})
    .then(() => console.log('success'))
    .catch(() => console.log('erroe'));
    

    1.9 创建数据库

    在MongoDB中不需要显式创建数据库,如果正在使用的数据库不存在,MongoDB会自动创建

    2.增删改查操作

    2.1 创建集合mongoose.Schema&model()

    创建集合分为两步,一是对对集合设定规则,二是创建集合,创建mongoose.Schema构造函数的实例即可创建集合

      // 1.定义集合规则
     const courseSchema = new mongoose.Schema({
         name: String,
         author: String,
         isPublished: Boolean
     });
      // 2.定义集合并应用规则  
     const Course = mongoose.model('Course', courseSchema); // courses
    
    

    2.2 创建文档create()

    创建文档实际上就是向集合中插入数据
    分为两步:
    1、创建集合实例
    2、调用实例对象下的save方法将数据保存到数据库中

    // 1.创建集合实例
    const course =  new Course({
        name: 'database',
        author: 'cc',
        isPublished: false
    });
    // 2.将文档插入到数据库中
    course.save();
    

    创建文档的第2种方法: 通过构造函数的create方法

    Course.create({name: 'database', author: 'ccc', isPublished: false}, (err, doc) => {
        // 错误对象
        console.log(err);
        // 当前插入的文档
        console.log(doc);
    });
    
    // Course.create()可以返回promise对象
    Course.create({name: 'database', author: 'ccc', isPublished: false})
    .then(doc => console.log(doc))
    .catch(err => console.log(err));
    

    2.3 数据库导入数据

    找到mongodb数据库的安装目录,将安装目录下的bin目录放置在环境变量中,接着到json目录下输入,mongoimport –d 数据库名称 –c 集合名称 –-file 要导入的数据文件

    mongoimport -d Course_demo -c users --file ./user.json
    

    此时报错,JSON decoder out of sync

    解决方法:将 --jsonArray 标志添加到命令中

    mongoimport -d Course_demo -c users --jsonArray --file ./user.json
    

    此时没有数据库Course_demo或者集合users,自动创建,向其追加json数据

    2.4 查询文档

    2.4.1 find()

    // 根据条件查找文档 返回数组(参数为空则查找所有文档)
    Course.find({_id: '5f3620c55bdba23230ef58fc'}).then(res=>console.log(res));
    
    // 返回文档集合
    [
      {
        _id: 5f3620c55bdba23230ef58fc,
        name: 'database',
        author: 'ccc',
        isPublished: false,
        __v: 0
      }
    ]
    
    

    2.4.2 findOne()

    // 2. 根据条件查找文档 返回一个对象(匹配的第一条文档)
    Course.findOne({_id: '5f361e2a23a10222804d76ad'}).then(res=>console.log(res));
    
    // 返回文档
    {
      _id: 5f361e2a23a10222804d76ad,
      name: 'database',
      author: 'ccc',
      isPublished: false,
      __v: 0
    }
    

    2.4.3 常用查询操作

     //  匹配大于 小于
     User.find({age: {$gt: 20, $lt: 50}}).then(result => console.log(result))
     //  匹配包含
     User.find({hobbies: {$in: ['吃饭']}}).then(result => console.log(result))
     //  选择要查询的字段  id默认得到,不需要时"-"
     User.find().select('name email -_id').then(result => console.log(result))
     // 将数据按照年龄进行排序
     User.find().sort('age').then(result => console.log(result))
     //  skip 跳过多少条数据  limit 限制查询数量
     User.find().skip(2).limit(2).then(result => console.log(result))
    
    
    const mongoose = require('mongoose');
    //1. 连接数据库
    mongoose.connect('mongodb://localhost/Course_demo', { useNewUrlParser: true ,useUnifiedTopology: true});
    //2. 定义集合规则
    const userSchema = new mongoose.Schema({
        "name": String,
        "age": Number,
        "password": String,
        "email": String,
        "hobbies": [String]
    });
    //3. 创建集合
    const User = mongoose.model('User', userSchema);
    User.find({
        //4. 条件筛选
        age: {$gt: 18, $lt: 40}
        hobbies: {$in: ['吃','睡觉']}//字段包含的文本
    }).select('name age hobby -_id')//结果包含和不包含的字段
    .sort('age')
    .skip(2)//跳过前两条文档
    .limit(10)
    .then(res => console.log(res));
    
    //输出结果
    [
      { name: '张三3', age: 20 },
      { name: '张三4', age: 20 },
      { name: '张三5', age: 20 },
      { name: '张三6', age: 20 },
      { name: '张三7', age: 20 },
      { name: '张三8', age: 20 },
      { name: '张三9', age: 20 },
      { name: '张三9', age: 20 },
      { name: '张三9', age: 20 },
      { name: '张三9', age: 20 }
    ]
    

    2.5 删除文档

     // 删除单个
    Course.findOneAndDelete({}).then(result => console.log(result))
     // 删除多个(不传参删除全部)
    User.deleteMany({}).then(result => console.log(result))
    
    
    User.findOneAndDelete({
        name: '张三5'
    }).then(res => console.log());
    //输出结果为删除的文档
    
    User.deleteMany({}).then(res => console.log(res));
    //输出结果
    { n: 10, ok: 1, deletedCount: 10 }//ok为删除成功 n为删除个数
    

    2.6 更新文档

    // 更新单个
    User.updateOne({查询条件}, {要修改的值}).then(result => console.log(result))//更新匹配的第一个
    // 更新多个
    User.updateMany({查询条件}, {要更改的值}).then(result => console.log(result))
    
    
    User.updateOne({name: "张三1"}, {name: "李四"})
    .then(res => console.log(res));
    //输出结果
    { n: 1, nModified: 1, ok: 1 }//更新成功 更新1条
    
    User.updateMany({}, {age: 56})
    .then(res => console.log(res));
    { n: 10, nModified: 10, ok: 1 }//更新成功 更新10条
    

    2.6 mongoose验证

    在创建集合规则时,可以设置当前字段的验证规则,验证失败就则输入插入失败

    • required: true 必传字段
    • minlength:3 字符串最小长度
    • maxlength: 20 字符串最大长度
    • min: 2 数值最小为2
    • max: 100 数值最大为100
    • enum: ['html', 'css', 'javascript', 'node.js'] 数值必须为数组中的元素
    • trim: true 去除字符串两边的空格
    • validate: 自定义验证器
    • default: 默认值

    获取错误信息:error.errors['字段名称'].message

    const postSchema = new mongoose.Schema({
        title: {
            type: String,
            required: true //必需字段
        }
    });
    const Post = mongoose.model('Post', postSchema);
    
    Post.create({}).then(res => console.log(res));
    //报错:ValidationError验证错误
    

    验证规则的使用:

    const mongoose = require('mongoose');
    
    mongoose.connect('mongodb://localhost/Course_demo', { useNewUrlParser: true ,useUnifiedTopology: true})
    
    const postSchema = new mongoose.Schema({
        title: {
            type: String,
            required: [true, '请传入文章标题'],//1. 自定义错误信息
            minlength: 2,
            maxlength: [5, '文章长度最大不超过5'],
            trim: true
        },
        age: {
            type: Number,
            min: 18,
            max: 100
        },
        date: {
            type: Date,
            default: Date.now   //2.不传时 默认添加当前时间
        },
        category: {
            type: String,
            enum: {
                values: ['html', 'css', 'js'],
                message: '分类名称要在一定范围内'
            } //3.传入规定 及错误信息
        },
        author: {
            type: String,
            // 4.自定义验证器
            validate: {
                validator: v => {
                    // 返回布尔值 验证v是否符合验证规则 
                    return v && v.length > 4
                },
                message: '传入不符合规则'
            }
        }
    });
    
    const Post = mongoose.model('Post', postSchema);
    
    Post.create({title: '  aaaaaa  ', age: 56, category: 'c++', author: 'cc'})
    .then(res => console.log(res))
    .catch(err => {
        // 5.获取错误信息对象
        const errs = err.errors;
        // 获取错误信息字段中的错误描述信息
        for(var attr in errs) {
            console.log(errs[attr].message);
        }
    });
    //输出:
    // 文章长度最大不超过5
    // 分类名称要在一定范围内
    // 传入不符合规则
    

    2.7 集合关联

    通常不同集合的数据之间是有关系的,例如文章信息和用户信息存储在不同集合中,但文章是某个用户发表的,要查询文章的所有信息包括发表用户,就需要用到集合关联

    • 使用id对集合进行关联
    • 使用populate方法进行关联集合查询
    const mongoose = require('mongoose');
    mongoose.connect('mongodb://localhost/Course_demo', { useNewUrlParser: true ,useUnifiedTopology: true})
    // 用户集合规则
    const userSchema = new mongoose.Schema({
        name: {
            type: String,
            required: true
        }
    });
    // 文章集合规则
    const postSchema = new mongoose.Schema({
        title: {
            type: String
        },
        author: {
            type: mongoose.Schema.Types.ObjectId, //id的类型
            ref: 'User' //关联的集合
        }
    });
    
    const User = mongoose.model('User', userSchema);
    const Post = mongoose.model('Post', postSchema);
    
    User.create({name: '李思'})
        .then(res => console.log(res));
    // 1. 使用id对集合进行关联
    Post.create({title: '123', author: '5f3655541d07b61a004753ad'})
        .then(res => console.log(res));
    // 2. 使用populate方法对某个字段 进行关联集合查询
    Post.find().populate('author').then(res => console.log(res));
    
    //输出
    [
      {
        _id: 5f3655f7ed385f28d4fc99a7,
        title: '123',
        author: { _id: 5f3655541d07b61a004753ad, name: '李思', __v: 0 },
        __v: 0
      }
    ]
    

    相关文章

      网友评论

          本文标题:mongodb笔记

          本文链接:https://www.haomeiwen.com/subject/oxctjktx.html