Node.js数据库开发实战之mongodb

举报
lwq1228 发表于 2021/09/10 14:29:23 2021/09/10
【摘要】 Node.js数据库开发实战之mongodb,通过mongoose和直接连接两种方式连接操作和使用mongodb数据库。

一、创建项目

(1)使用WebStorm创建node-mongodb项目

(2)创建完成后,项目会自动打开,如下图

说明:后续两种连接mongodb的例子均基于此项目。

二、使用mongoose连接mongodb

mongoose是一个基于node-mongodb-native开发的mongodb的Node.js驱动,可以很方便地在异步环境中使用。

1、安装mongoose

在WebStorm的Terminal中使用npm安装mongoose:

npm install mongoose

安装完成如下图:

2、连接数据库

mongoose模块通过connect()方法与mongodb创建连接。connect()方法中需要传递一个URI地址,用来说明需要连接的mongodb数据库。如下代码就和服务器172.16.2.103的mongodb数据库node_test建立了连接。

测试代码:

//引入mongoose模块
const mongoose = require('mongoose');
//定义mongodb地址
const uri = 'mongodb://root:123456@172.16.2.103:27017/node_test?authSource=admin';
//连接mongodb
mongoose.connect(uri, function (err) {
        if (err) {
            console.log('连接失败');
            console.log(err);
            return;
        }
        console.log('连接成功');
    }
);

测试结果:

代码说明:

connect()方法创建mongodb连接,回调函数中err为参数,出现连接错误则打印出“连接失败”,连接成功则打印出“连接成功”。运行这段代码,如果mongodb服务已经正常开启,就会在控制台打印出“连接成功”字样。

需要说明的是,connect()方法中uri参数的完整示例应该是:

mongodb://user:pass@host:port/database

user:代表mongodb的用户名
pass:代表用户名对应的密码
host:代表mongodb服务的IP地址
port:代表mongodb服务的端口号
database:代表对应的数据库名
?authSource=admin:用于做授权验证的数据库,如果不加,后续保存数据会报错

3、保存数据

mongoose中的一切由schema开始。schema是一种以文件形式存储的数据库模型骨架,并不具备数据库的操作能力。schema中定义了model中的所有属性,而model则是对应一个mongodb中的collection。以下代码定义了一个schema并且注册成了一个model:

测试代码:

//引入mongoose模块
const mongoose = require('mongoose');
//定义mongodb地址
const uri = 'mongodb://root:123456@172.16.2.103:27017/node_test?authSource=admin';
//连接mongodb
mongoose.connect(uri, function (err) {
        if (err) {
            console.log('连接失败');
            console.log(err);
            return;
        }
        console.log('连接成功');
    }
);

/**
 * 定义UserSchema
 * @type {mongoose.Schema}
 */
const UserSchema = new mongoose.Schema({
    name: String,
    age: Number,
    sex: String,
    birth: Date
});
mongoose.model('User', UserSchema);

这段代码通过实例化一个mongoose.Schema()对象定义一个model的所有属性,类似于关系型数据库中的字段和字段的数据类型。schema合法的类型有String、Number、Date、Buffer、Boolean、Mixed、Objectid和Array。mongoose中通过mongoose.model()方法注册一个model。在mongoose中可以调用save()方法将一个新的文档插入到已有的collection中,代码如下:

//引入mongoose模块
const mongoose = require('mongoose');
//定义mongodb地址
const uri = 'mongodb://root:123456@172.16.2.103:27017/node_test?authSource=admin';
//连接mongodb
mongoose.connect(uri, function (err) {
        if (err) {
            console.log('连接失败');
            console.log(err);
            return;
        }
        console.log('连接成功');
    }
);

/**
 * 定义UserSchema
 * @type {mongoose.Schema}
 */
const UserSchema = new mongoose.Schema({
    name: String,
    age: Number,
    sex: String,
    birth: Date
});
mongoose.model('User', UserSchema);

const User = mongoose.model('User');
const user = new User({
    name: '张三',
    age: 25,
    sex: '男',
    birth: new Date()
});
/**
 * 将文档插入到集合中
 */
user.save(function (err) {
    if (err) {
        console.log('保存失败');
        console.log(err);
    } else {
        console.log('保存成功');
    }
});

测试结果:

提示保存成功,查看数据库,可以看到数据库自动创建了users集合,并且数据已经保存了:

代码说明:

这段代码调用名为User的model,之后定义了一个User的文档,最后使用save将记录插入到相应的collection中。save()方法中的回调函数监听是否出错。运行这段代码,在mongodb运行正常的情况下,控制台将输出“保存成功”字样。

4、查询数据集

使用mongoose可以查询mongodb相应的数据。如下代码可以将users这个collection中的所有文档查询出来:

测试代码1:

//引入mongoose模块
const mongoose = require('mongoose');
//定义mongodb地址
const uri = 'mongodb://root:123456@172.16.2.103:27017/node_test?authSource=admin';
//连接mongodb
mongoose.connect(uri, function (err) {
        if (err) {
            console.log('连接失败');
            console.log(err);
            return;
        }
        console.log('连接成功');
    }
);

/**
 * 定义UserSchema
 * @type {mongoose.Schema}
 */
const UserSchema = new mongoose.Schema({
    name: String,
    age: Number,
    sex: String,
    birth: Date
});
mongoose.model('User', UserSchema);

const User = mongoose.model('User');
/**
 * 查询mongodb
 */
User.find({}, function (err, docs) {
    if (err) {
        console.log('查询失败');
        return;
    }
    console.log("查询结果:" + docs);
});

测试结果1:

代码说明1:

这段代码通过find()方法查找相应的数据记录。find()方法中的第一个参数是一个json对象,定义查找的条件,第二个参数为回调函数。回调函数中的第一个参数是error,第二个参数是查询的结果。在find()方法中的第一个参数中可以传入筛选条件,以便更加精确地查找出需要查找的数据。现将find()方法的代码修改为以下代码:

测试代码2:

User.find({name: '张三'}, function (err, docs) {
    if (err) {
        console.log('查询失败');
        return;
    }
    console.log("查询结果:" + docs);
});

运行这段代码只查询出name是”张三“的数据:

5、查询并修改数据

在mongoose中可以直接在查询记录后修改记录的值,修改后直接调用保存以保存修改后的数据。如下代码查询数据后直接修改数据的name值为“李四”。

测试代码:

//引入mongoose模块
const mongoose = require('mongoose');
//定义mongodb地址
const uri = 'mongodb://root:123456@172.16.2.103:27017/node_test?authSource=admin';
//连接mongodb
mongoose.connect(uri, function (err) {
        if (err) {
            console.log('连接失败');
            console.log(err);
            return;
        }
        console.log('连接成功');
    }
);

/**
 * 定义UserSchema
 * @type {mongoose.Schema}
 */
const UserSchema = new mongoose.Schema({
    name: String,
    age: Number,
    sex: String,
    birth: Date
});
mongoose.model('User', UserSchema);

const User = mongoose.model('User');
/**
 * 查询mongodb
 */
User.find({name: '张三'}, function (err, docs) {
    if (err) {
        console.log('查询失败');
        return;
    }
    // 修改数据
    docs[0].name = '李四';
    //保存修改后的数据
    docs[0].save();
    console.log("查询结果:" + docs);
});

测试结果:

通过Navicat查看数据库,数据已经更新:

6、删除数据

类似于修改数据,删除mongodb的文档也可以在查询出文档后直接调用remove方法。如下代码可以删除users集合中的所有文档:

测试代码:

//引入mongoose模块
const mongoose = require('mongoose');
//定义mongodb地址
const uri = 'mongodb://root:123456@172.16.2.103:27017/node_test?authSource=admin';
//连接mongodb
mongoose.connect(uri, function (err) {
        if (err) {
            console.log('连接失败');
            console.log(err);
            return;
        }
        console.log('连接成功');
    }
);

/**
 * 定义UserSchema
 * @type {mongoose.Schema}
 */
const UserSchema = new mongoose.Schema({
    name: String,
    age: Number,
    sex: String,
    birth: Date
});
mongoose.model('User', UserSchema);

const User = mongoose.model('User');
/**
 * 查询mongodb
 */
User.find({}, function (err, docs) {
    if (err) {
        console.log('查询失败');
        return;
    }
    if (docs) {
        //删除数据
        docs.forEach(function (item) {
            item.remove();
        });
        console.log('删除成功');
    }
});

测试结果:

通过Navicat查看数据库,数据已经删除:

代码说明:

只有单个文档可以调用remove()方法,因为find()方法返回的是一个符合查询条件的所有文档组成的数组,所以这里调用数组的forEach()方法逐个删除所有的文档。

三、直接连接mongodb

二中提到了mongoose模块是基于node-mongodb-native开发的mongodb的Node.js驱动,同样使用node-mongodb-native这个原生mongodb驱动也可以对mongodb进行相应的操作。

1、安装mongodb

使用node-mongodb-native这个模块前需要安装mongodb模块,在WebStorm的Terminal中使用npm安装mongodb:

npm install mongodb

安装完成如下图:

2、连接数据库

node-mongodb-native通过connect()方法传递一个URI地址,用来说明需要连接的mongodb数据库。如下代码即和服务器172.16.2.103的mongodb数据库node_test建立了连接。

测试代码:

//引入模块
const MongoClient = require('mongodb').MongoClient;
//定义mongodb地址
const uri = 'mongodb://root:123456@172.16.2.103:27017/node_test?authSource=admin';
//连接mongodb
MongoClient.connect(uri, function (err, db) {
        if (err) {
            console.log('连接失败');
            console.log(err);
            return;
        }
        console.log('连接成功');
    }
);

测试结果:

代码说明:

因为mongoose是基于node-mongodb-native开发的,所以两者的API还是有相似的地方。运行以上这段代码,如果mongodb运行正常,将会打印出“连接成功”字样。

3、保存数据

使用node-mongodb-native驱动需要注意:每次操作完mongodb都应该调用close方法来关闭mongodb,否则会影响其他代码对mongodb的操作。调用insertOne方法可以插入一条数据,如前面提到的一样,node-mongodb-native插入的数据依旧是json格式,代码如下:

测试代码:

//引入模块
const MongoClient = require('mongodb').MongoClient;
//定义mongodb地址
const uri = 'mongodb://root:123456@172.16.2.103:27017/node_test?authSource=admin';
//连接mongodb
MongoClient.connect(uri, function (err, db) {
        if (err) {
            console.log('连接失败');
            console.log(err);
            return;
        }
        console.log('连接成功');

        /**
         * 定义数据
         */
        const user = {
            name: '张三',
            age: 30,
            sex: '男',
            birth: new Date()
        }

        const dbase = db.db('node_test');
        //打开集合
        dbase.collection('users').insertOne(user, function (err, doc) {
            //关闭数据库
            db.close();
            if (err) {
                console.log('执行失败');
                console.log(err);
                return;
            }
            console.log('数据添加成功');
        });
    }
);

测试结果:

通过Navicat查看数据库,数据已经被添加:

代码说明:

这段代码将一个名为“张三”的用户数据插入到node_test数据库下的users集合中,整个过程是连接数据库→打开集合→插入数据→关闭数据库。如果想保存多条数据,可以使用insertMany(),第一个参数传入一个Json数组即可。

4、查询数据

使用mongoose可以查询mongodb相应的数据。如下代码可以将users这个collection中的所有文档查询出来:

测试代码1:

//引入模块
const MongoClient = require('mongodb').MongoClient;
//定义mongodb地址
const uri = 'mongodb://root:123456@172.16.2.103:27017/node_test?authSource=admin';
//连接mongodb
MongoClient.connect(uri, function (err, db) {
        if (err) {
            console.log('连接失败');
            console.log(err);
            return;
        }
        console.log('连接成功');

        const dbase = db.db('node_test');
        //打开集合
        dbase.collection('users').find({}).toArray(function (err, result) {
            //关闭数据库
            db.close();
            if (err) {
                console.log('查询失败');
                console.log(err);
                return;
            }
            console.log(result);
        });
    }
);

测试结果1:

代码说明1:

整个过程也是按照连接数据库→打开集合→查询数据→关闭数据库这个流程严格执行的。在find()方法中的参数中可以传入Json格式的筛选条件,以便更加精确地查找出需要查找的数据。现将find()方法的代码修改为以下代码:

测试代码2:

//引入模块
const MongoClient = require('mongodb').MongoClient;
//定义mongodb地址
const uri = 'mongodb://root:123456@172.16.2.103:27017/node_test?authSource=admin';
//连接mongodb
MongoClient.connect(uri, function (err, db) {
        if (err) {
            console.log('连接失败');
            console.log(err);
            return;
        }
        console.log('连接成功');

        const dbase = db.db('node_test');
        //打开集合
        dbase.collection('users').find({name: '李四'}).toArray(function (err, result) {
            //关闭数据库
            db.close();
            if (err) {
                console.log('查询失败');
                console.log(err);
                return;
            }
            console.log(result);
        });
    }
);

运行这段代码同样只查询出name为“李四“的数据:

5、修改数据

node-mongodb-native模块的updateOne()方法可以更改数据,与查询方法类似。updateOne()方法的第一个参数是查询条件,第二个参数是更改后的数据,第三个参数是一个处理错误和结果的回调函数。如下代码就可以将“李四”这条数据的年龄改为32。

测试代码:

//引入模块
const MongoClient = require('mongodb').MongoClient;
//定义mongodb地址
const uri = 'mongodb://root:123456@172.16.2.103:27017/node_test?authSource=admin';
//连接mongodb
MongoClient.connect(uri, function (err, db) {
    if (err) {
        console.log('连接失败');
        console.log(err);
        return;
    }
    console.log('连接成功');

    const dbase = db.db('node_test');
    // 更新条件
    const whereStr = {name: '李四'};
    // 更新的数据
    const updateStr = {$set: {age: 32}};
    //打开集合
    dbase.collection('users').updateOne(whereStr, updateStr, function (err, res) {
        //关闭数据库
        db.close();
        if (err) {
            console.log('查询失败');
            console.log(err);
            return;
        }
        console.log('文档更新成功');
    });
});

测试结果:

通过Navicat查看数据库,数据已经更新:

代码说明:

如果要更新所有符合条的文档数据可以使用 updateMany()。

6、删除数据

类似于修改数据,删除mongodb的文档也可以在查询出文档后直接调用remove方法。如下代码可以删除users集合中的所有文档:

测试代码:

//引入模块
const MongoClient = require('mongodb').MongoClient;
//定义mongodb地址
const uri = 'mongodb://root:123456@172.16.2.103:27017/node_test?authSource=admin';
//连接mongodb
MongoClient.connect(uri, function (err, db) {
    if (err) {
        console.log('连接失败');
        console.log(err);
        return;
    }
    console.log('连接成功');

    const dbase = db.db('node_test');
    // 删除条件
    const whereStr = {name: '李四'};
    //打开集合
    dbase.collection('users').deleteOne(whereStr, function (err, obj) {
        //关闭数据库
        db.close();
        if (err) {
            console.log('删除失败');
            console.log(err);
            return;
        }
        console.log('文档删除成功');
    });
});

测试结果:

通过Navicat查看数据库,数据已经删除:

代码说明:

如果要删除多条语句可以使用 deleteMany() 方法。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。