zoukankan      html  css  js  c++  java
  • Node教程——MongoDB数据库

    MongoDB数据库讲解

    为什么要使用数据库?

    在互联网上的网站主要有两大类,静态的还有动态的,关于静态的网站不必多说,所谓的动态网站就是可以根据对应的请求拿到不同的结果,什么意思呢,只可意会吧,你只需要知道动态网站是目前的标配就完事了

    我们为什么要用MongoDB?mysql行不行?当然没有问题。但是!学习MongoDB的学习成本比较低,什么意思呢?我的意思是,由于MongoDB数据库开发的接口是js的语法,还有内部的存储格式是json所有你特别容易上手,

    MongoDB是一个软件,去下载吧少年

    这里需要两个软件,一个是本身的数据库软件,还有一个可视化的数据库软件
    百度点击下载就完事!我认为我这里没有必要教你如何安装软件
    需要说明的一件事,你需要知道这两个文件夹,方便后面的排错
    如何查看你的MongoDB已经安装成功?其实这个软件会在你的电脑上开一个端口
    localhost:27017,如果你访问没有报错,就说明你成功安装了这个软件

    数据库基础知识

    1. 数据仓库,database
      所谓的数据仓库,指的是一个数据库软件,可以提供给多个网站进行服务,每一个网站都有自己的对应的数据仓库,仓库里就是关于本网站的数据内容
    2. 集合,collection
      集合是在仓库下,一组数据的集合,可以理解为js的数组
    3. 文档,document
      集合下面有文档,文档是一条具体的数据,类似于js中的对象
    4. 字段,field
      文档里面有数据对应的字段,什么是字段?就相当于js中的键值对中的键,当然你也可以理解为对象的属性

    有点模糊?没关系。看下面的这个图,你就会感觉爽多了

    使用数据库(一)

    1. 首先,我们打开我们的软件。你不需要做任何的修改,直接点击链接,就完事。

    2. 第二步,我们看看数据库里面有什么 注意这里的admin还有config还有local不要动!!!
      点击创建就可以创建仓库了,我们先创建一个名字叫做api的仓库

    1. 再然后我们创建一个仓库,下面的的就是我的数据库了,里面的所有的东西,这里的创建还是非常简单的,由于提供了可视化软件,所以操作非常的容易

    2. 那么你可能郁闷了,哇这么多的字段还有数据,老李,你让我一个一个打吗?你在想屁吃吧,
      没关系!就知道你们懒啊,我们可以下面的方式直接导入现有的数据,注意啊,这里你不能再使用之前的GUI软件了,我们换一个软件,接下里的开发都在这里面进行,MongoBooster,
      使用说明:你直接百度一下吧,使用去起来非常的简单!拖拽json文件回去就可以完成一次数据库的导入

    使用数据库(二)

    你以为会用GUI就完事了??不不不不,你是程序员,大哥!你需要用代码!!!

    1. 在Node中下载一个依赖npm install mongoose,这样你才能通过Node操作数据库
    2. 在在电脑中启动MongoDB,用到两个命令。开启服务:net start mongoDB 关闭服务:net stop mongoDB
    3. 在node中链接到自己的数据库
      语法:
    // 注意我们的返回的是一个promise对象
    // 引入mongoose第三方模块 用来操作数据库
    const mongoose = require('mongoose');
    // 数据库连接
    //这个是返回一个promise对象,(异步,
    //这个地方没有playground也是ok的,如果没有他会自己帮我创建这个数据库
    // { useNewUrlParser: true }这个参数不用管你加上就完事
    mongoose.connect('mongodb://localhost/playground', { useNewUrlParser: true })
        // 连接成功
        .then(() => console.log('数据库连接成功'))
        // 连接失败
        .catch(err => console.log(err, '数据库连接失败'));
    

    使用数据库(三,增)

    导学:我们的库如果没有就会自动创建一个库,

    有了库,我们就可创建库的下一个级别:集合

    • 第一种创建方式
    1. 第一步:设置集合的规则
    const mongoose = require('mongoose');
    //对集合设定规则
      // 设定集合规则
     const courseSchema = new mongoose.Schema({
         name: String,
         author: String,
         isPublished: Boolean
     });
      // 创建集合并应用规则
    
    1. 第二步:创建集合,获得一个代表当前集合的集合构造函数,这个集合构造函数非常 重要
     const Course = mongoose.model('Course', courseSchema); // Course就是集合的名字。注意这里你需要给一个大写,
     //返回一个构造函数,然后我们拿东西去接过来就完事
    
    
    1. 第三步,往数据库里面丢一点东西
    
    //5.注意你需要插进数据,要不然它不会创建出来
    
    // 6.把集合实例创建出来,并且把数据传入,于是乎你就有了一个数据对象,也就是创建文档
    let coures = new Course({
        name: 'node教程',
        author: '老李',
        isPublished: true
    })
    
    
    // 7.调用集合对象下的方法 插入数据
    coures.save()
    
    • 我们还有一种方式
    
    // 第一个是数据库。第二个回调函数
    //Course是之前的的构造函数
       Course.create({name: 'JavaScript基础', author: '老李', isPublish: true}, (err, doc) => { 
        //  错误对象
       console.log(err)
        //  当前插入的文档
       console.log(doc)
    });
    
    //有回调函数的时候基本上都是异步的api,Course.create()返回promise对象
    Course.create({name: 'Node基础', author: '老李', isPublish: true})
         .then(doc => console.log(doc))
         .catch(err => console.log(err))
    
    
    • 导入现有的数据,通过代码

    基础的语法是这样的-在命令行。这个是命令不是代码:

    mongoimport –d 数据库名称 –c 集合名称 –file 要导入的数据文件
    

    小心:一般来说,如果是为window系统添加一些命令 你需要像下面的样子一样去设置

    找到mongodb数据库的安装目录,将安装目录下的bin目录放置在环境变量中。

    mongoimport -d playground -c users -file .user.json

    使用数据库(四,删)

    注意我们的所有的数据的操作的api都是在Coures集合构造函数下的,我的意思是:之前我们说的集合构造函数,非常的重要!

    删除文档的语法:注意,他们都是返回promise对象,then之后都是拿到的被删除的文档,{}里卖是丢查询条件
     // 删除单个
    Course.findOneAndDelete({}).then(result => console.log(result))
     // 删除多个 返回,一个对象ok:1表示操作成功。n:表示删除四个
    User.deleteMany({}).then(result => console.log(result))
    
    
    

    使用数据库(五,改)

    注意我们的所有的数据的操作的api都是在Coures集合构造函数下的,我的意思是:之前我们说的集合构造函数,非常的重要!

    其实啊改的操作,也就是更新操作

    基础的语法:

    // 更新单个
    User.updateOne({查询条件}, {要修改的值}).then(result => console.log(result))
    // 更新多个
    User.updateMany({查询条件}, {要更改的值}).then(result => console.log(result))
    

    实战演示:

    // 找到要删除的文档并且删除
    // 返回是否删除成功的对象
    // 如果匹配了多条文档, 只会删除匹配成功的第一条文档
    // User.updateOne({name: '李四'}, {age: 120, name: '李狗蛋'}).then(result => console.log(result))
    // 找到要删除的文档并且删除
    // 如果传递的是一个{} 表示修改所有的
    User.updateMany({}, { age: 300 }).then(result => console.log(result))
    

    使用数据库(六,查)

    注意我们的所有的数据的操作的api都是在Coures集合构造函数下的,我的意思是:之前我们说的集合构造函数,非常的重要!
    它在这里

    const Course = mongoose.model('Course', courseSchema); // Course就是集合的名字。注意这里你需要给一个大写,
     //返回一个构造函数,然后我们拿东西去接过来就完事
    

    看看我们的怎么做查询操作
    语法:

    //  根据条件查找文档(条件为空则查找所有文档)
     当前的集合构造函数.find().then(result => console.log(result))
    注意它的返回值:数组,如果查询的数据不存在就会返回一个空数组
    
    
    +++
    // 引入mongoose第三方模块 用来操作数据库
    const mongoose = require('mongoose');
    // 数据库连接
    mongoose.connect('mongodb://localhost/playground', { useNewUrlParser: true })
        // 连接成功
        .then(() => console.log('数据库连接成功'))
        // 连接失败
        .catch(err => console.log(err, '数据库连接失败'));
    
    // 创建集合规则
    const userSchema = new mongoose.Schema({
        name: String,
        age: Number,
        email: String,
        password: String,
        hobbies: [String] //这个是一个数组,数组里面是字符串
    });
    
    // 使用规则创建集合
    const User = mongoose.model('User', userSchema); //返回是一个集合的构造函数
    
    // 查询文档
    // 查询用户集合中的所有文档
    // User.find().then(result => console.log(result)); //find方法。返回的总是一个文档的集合(数组,需要说明的是,.then是promise对象的方法,这个返回的是程序的结果
    // 通过_id字段查找文档
    // User.find({ _id: '5c09f267aeb04b22f8460968' }).then(result => console.log(result))
    
    // findOne方法返回一条文档 默认返回当前集合中的第一条文档
    // User.findOne({ name: '李四' }).then(result => console.log(result))
    // 查询用户集合中年龄字段大于20并且小于40的文档
    // User.find({ age: { $gt: 20, $lt: 40 } }).then(result => console.log(result)) //这里有一些转意字符,你需要了解$gt = >号,$lt = <号
    // 查询用户集合中hobbies字段值包含足球的文档,可以用于实现网站的搜索功能
    // User.find({hobbies: {$in: ['足球']}}).then(result => console.log(result)) //$in是包含的意思
    // 选择要查询的字段
    // User.find().select('name email -_id').then(result => console.log(result))
    // 根据年龄字段进行升序排列,可以用来实现价格的查询等等操作
    // User.find().sort('age').then(result => console.log(result))
    // 根据年龄字段进行降序排列
    // User.find().sort('-age').then(result => console.log(result))
    // 查询文档跳过前两条结果 限制显示3条结果,这个可以实现分页功能
    User.find().skip(2).limit(3).then(result => console.log(result))
    User.find().skip(2).limit(3).then(result => console.log(result))
    skip(2)跳过前两个文档
    limit(3)只想要三个
    +++
    
    总结:
    // 返回的都是文档
    find()是返回这个东西
    [{
        _id: 5c0917ed37ec9b03c07cf95f,
        name: 'node.js基础',
        author: 'laoli'
    },{
         _id: 5c09dea28acfb814980ff827,
         name: 'Javascript',
         author: 'laoli'
    }]
    
    findOne()返回是这个东西
    {
        _id: 5c0917ed37ec9b03c07cf95f,
        name: 'node.js基础',
        author: 'laoli'
    }
    
    

    验证

    上面意思呢?指的是设置设置字段的插入规则,验证一下看看你的字段符不符合我的规则,如果符合就允许用户插入字段

    需求:比如这里我们创建文章集合

    
    // 引入mongoose第三方模块 用来操作数据库
    const mongoose = require('mongoose');
    // 数据库连接
    mongoose.connect('mongodb://localhost/playground', { useNewUrlParser: true })
        // 连接成功
        .then(() => console.log('数据库连接成功'))
        // 连接失败
        .catch(err => console.log(err, '数据库连接失败'));
    
    //这里是做一些mongodb的验证,注意啊这里的规则可以是对象类型
    const postSchema = new mongoose.Schema({
        title: {
            type: String,
            // 必选字段
            required: [true, '请传入文章标题'],
            // 字符串的最小长度
            minlength: [2, '文章长度不能小于2'],
            // 字符串的最大长度
            maxlength: [5, '文章长度最大不能超过5'],
            // 去除字符串两边的空格
            trim: true
        },
        age: {
            type: Number,
            // 数字的最小范围
            min: 18,
            // 数字的最大范围
            max: 100
        },
        publishDate: {
            type: Date,
            // 默认值
            default: Date.now //这个是会传出一个日期,这个是默认的传入的
        },
        category: {
            type: String,
            // 枚举 列举出当前字段可以拥有的值,这个是枚举,
            // 所谓的枚举 就是一个一个举例验证出来
            enum: {
                values: ['html', 'css', 'javascript', 'node.js'],
                message: '分类名称要在一定的范围内才可以'
            }
        },
        author: {
            type: String,
            //我们程序员自定义的验证规则
            validate: {
                validator: v => { //v是形参,是当前用户插入的值
                    // 返回布尔值
                    // true 验证成功
                    // false 验证失败
                    // v 要验证的值
                    //短路运算
                    return v && v.length > 4
                },
                // 自定义错误信息
                message: '传入的值不符合验证规则,最少是4个以上1'
            }
        }
    });
    
    const Post = mongoose.model('Post', postSchema);
    
    //需求:如何一次性的把所有的不符合验证规则的错误信息都获取出来
    
    Post.create({ title: 'aa', age: 60, category: 'java', author: 'bd' })
        .then(result => console.log(result))
        .catch(error => {
            // 获取错误信息对象,这个获取过来的其实就是报错的信息
            const err = error.errors;
            // 循环错误信息对象
            for (var attr in err) { //注意一下这个地方的for遍历循环的操作要点
                // 将错误信息打印到控制台中
                console.log(err[attr]['message']);
            }
        })
    
    

    MongoDB高级——集合关联

    这个是比较难的
    需求:在一个数据中,包含其他的数据。

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

    使用id对集合进行关联
    使用populate方法进行关联集合查询

    语法规范:

    // 用户集合
    const User = mongoose.model('User', new mongoose.Schema({ name: { type: String } })); 
    // 文章集合
    const Post = mongoose.model('Post', new mongoose.Schema({
        title: { type: String },
        // 使用ID将文章集合和作者集合进行关联,是一个id的类型mongoose.Schema.Types.ObjectId,固定死的,第二个参数就是关联谁
        author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
    }));
    //联合查询
    Post.find()
          .populate('author')
          .then((err, result) => console.log(result));
    

    示例代码:

    // 引入mongoose第三方模块 用来操作数据库
    const mongoose = require('mongoose');
    // 数据库连接
    mongoose.connect('mongodb://localhost/playground', { useNewUrlParser: true })
        // 连接成功
        .then(() => console.log('数据库连接成功'))
        // 连接失败
        .catch(err => console.log(err, '数据库连接失败'));
    
    // 用户集合规则
    const userSchema = new mongoose.Schema({
        name: {
            type: String,
            required: true
        }
    });
    // 文章集合规则
    const postSchema = new mongoose.Schema({
        title: {
            type: String
        },
        author: {
            type: mongoose.Schema.Types.ObjectId, //注意一下 mongodb的id是有一种特殊类型的,这个就是那个类型
            ref: 'User' //ref就是关联的意思!指定关联另外一个集合
        }
    });
    // 用户集合 
    const User = mongoose.model('User', userSchema);
    // 文章集合
    const Post = mongoose.model('Post', postSchema);
    
    // 创建用户
    User.create({ name: 'itheima' }).then(result => console.log(result));
    // 创建文章
    Post.create({ titile: '123', author: '5c0caae2c4e4081c28439791' }).then(result => console.log(result));
    //查询作者
    Post.find().populate('author').then(result => console.log(result))
    
  • 相关阅读:
    [tp3.2.1]sql查询语句(一)
    [crunch bang]在Crunch Bang安装和设置fcitx(小企鹅输入法)
    [tp3.2.1]大D构建模型
    [tp3.2.1]数据模型
    [tp3.2.1]开启URL(重写模式),省略URL中的index.php
    [tp3.2.1]让默认页面: 加载Home模块的Index控制器;而让admin.php默认去加载Admin模块的Adminc控制器.
    [JAVA]在linux中设置JDK环境,ZendStudio,Eclipse
    [fedora21]给fedora21安装fcitx输入法
    Software--Architecture--Design DataAccess 数据访问
    leetcode--Algorithm--Array_Part 1 Easy- 566 Reshape the Matrix
  • 原文地址:https://www.cnblogs.com/BM-laoli/p/12661594.html
Copyright © 2011-2022 走看看