ITPub博客

首页 > 数据库 > > node-mongodb上手指南

node-mongodb上手指南

作者:浪花小雨滴 时间:2020-05-12 11:32:52 0 删除 编辑

文章转载自:node-mongodb上手指南


目录:

1. MongoDB介绍
2. MongoDB本地安装
3. MongoDB本地操作
    3.1 库操作
    3.2 表操作
4. node-mongodb安装
5. node-mongodb连接
6. node-mongodb语法和执行
    - 插入
    - 查询
    - 修改
    - 删除
    - 存储过程
7. node-mongoose介绍和使用
    7.1 mongoose名词介绍
    7.2 node-mongoose安装
    7.3 node-mongoose安装
    7.4 node-mongoose语法和执行
        7.4.1 Schema,Modal创建
            - 索引和默认值
            - 验证器
        7.4.2 数据库操作
            - 插入
            - 删除
            - 修改
                - 修改器和更新器
            - 查询
                - 条件查询
                - 数量查询
                - 根据id查询
                - 分页查询
            - aggregate
8. 其他


1.mongodb介绍

开源,高性能的NoSQL数据库;支持索引、集群、复制和故障转移、各种语言的驱动程序;高伸缩性;

2. mongodb本地安装

官方安装说明: docs.mongodb.org/manual

安装成功后启动:
我本地是:mongod --dbpath "f:\data\db"

MongoDB默认端口是27017;

3. mongodb本地操作

成功启动MongoDB后,再打开一个命令行窗口输入mongo,就可以进行数据库的一些操作

a. 库操作

新建数据库:第一步:use 新建数据库名;第二步:进行此库相关的操作;如果不进行第二步,该数据库不会被创建
- 查看数据库:show dbs;
- 新建表:db.createCollection('要新建的表名');
- 查看当前数据库下表: show collections;
- 删除当前数据库指定表:db.表名.drop();
- 删除当前数据库:db.dropDatabase();

提示:
1. 默认为存在“admin”和“local”两个数据库;admin数据库是存放管理员信息的数据库,认证会用到;local是存放replication相关的数据;这两处本篇都没有涉及到;
2. find();是个查询操作,后面会讲到,上面用到主要是为了演示use不存在的库后,进行相关操作会创建出这个库;
3. MongoDB没有像MySQL或MSSQL等数据库这么严格的规定,不是非得要先建库、建表、建各种字段,以后的操作中慢慢的会体会到^_^!

b. 表操作

1. 插入
方法一:db.表名.insert(数据);  
1. 没有去创建新表,其实通过插入操作也会自动创建
2. _id,是mongodb自已生成的,每行数据都会存在,默认是ObjectId,可以在插入数据时插入这个键的值(支持mongodb支持的所有数据类型)

方法二:db.表名.save(数据);     
1. save也可达到insert一样的插入效果
2. _id可以自已插入
3. 一个表中不一定要字段都相同

那它们有什么区别?  
  虽然insert和save方法都可以插入数据,当默认的“_id”值已存在时,调用insert方法插入会报错;而save方法不会,会更新相同的_id所在行数据的信息

2. 查询
- 查询表中所有数据:db.表名.find();
- 按条件查询(支持多条件):db.表名.find(条件);
- 查询第一条(支持条件):db.表名.findOne(条件);
- 限制数量:db.表名.find().limit(数量);
- 跳过指定数量:db.表名.find().skip(数量);

查询不止这些,还有些高级查询,自行去了解一下^_^!

3. 修改
- 前面save在_id字段已存在是就是修改操作,按指定条件修改语法如下:
- db.表名.update({"条件字段名":"字段值"},{$set:{"要修改的字段名":"修改后的字段值"}});

4. 删除
- db.表名.remove(条件);

5. 存储过程

// 创建存储过程:
db.system.js.save({_id:"存储过程ID", 
value:function(参数){  
        -- 逻辑主体; 
        return 返回; 
}});                
// 调用存储过程
db.eval("存储过程ID()");

所有存储过程都存放在db.system.js中

4. node-mongodb安装

npm install mongodb

5. node-mongodb连接

  1. 创建连接对象,需要传入连接数据库的一些连接参数
const mongodbClient = require('mongodb').MongoClient;
    const url = 'mongodb://locolhost:27017';
    const dbName = 'test'; // 数据库名称

    mongodbClient.connect(url, function(err, client){
      console.log('连接成功!');
      const db = client.db(dbName);
      const collection = db.collection('test'); // 连接到表
      // 执行mongo语句
      ......        
      client.close(); // 关闭连接  
    })
  1. 关闭连接
    关闭一个连接使用close();

6. node-mongodb语法和执行

a. 插入

const insertData = function(collection, callback) {   
  //插入数据
  const data = [{"name":'zhangsan',"age":21},{"name":'lisi',"age":22}];
  collection.insert(data, function(err, result) { 
      if(err){
          console.log('Error:'+ err);
          return;
      }     
      callback(result);
  });
}
mongodbClient.connect(url, function(err, client){
  console.log('连接成功!');
  const db = client.db(dbName);
  const collection = db.collection('test');
  insertData(collection, function(result){
    console.log(result);
  });
})

b. 查询

const selectData = function(collection, callback) {  
  // 查询所有
  let whereStr = {"name":"张三"};
  collection.find(whereStr).toArray(function(err, result) {
    if(err){
      console.log('Error:'+ err);
      return;
    }     
    callback(result);
  });
  // 条件查询 查询参数很多,自行查阅
  collection.find({"age":{$gt:30}}).toArray(function(err, result) {
    if(err)
    {
      console.log('Error:'+ err);
      return;
    }     
    callback(result);
  });
}
......

c. 修改

const updateData = function(collection, callback) {  
    const whereStr = {"name":'zhangsan'};
    const updateStr = {$set: { "age" : 100 }};
    collection.update(whereStr, updateStr, function(err, result) {
        if(err){
            console.log('Error:'+ err);
            return;
        }     
        callback(result);
    });
}

d: 删除

var delData = function(db, callback) {  
  //连接到表  
  var collection = db.collection('tb2');
  //删除数据
  var whereStr = {"name":'wilson001'};
  collection.remove(whereStr, function(err, result) {
    if(err)
    {
      console.log('Error:'+ err);
      return;
    }     
    callback(result);
  });
}

e: 存储过程

const invokeProcData = function(db, callback) {  
    db.eval('get_tb2_count()', function(err, result) { 
        if(err)
        {
            console.log('Error:'+ err);
            return;
        }             
        callback(result);
    });
}

7. mongoose介绍和使用

一般我们不直接用MongoDB的函数来操作MongoDB数据库,针对它的进行再次封装的东西很多,且更利于编程实现,比如:mongoose、mongoskin、mongolian等等,应用性不错;

Mongoose就是一套操作MongoDB数据库的接口,且应用较多。

1. 名词解释

  • Schema: 一种以文件形式存储的数据库模型骨架,不具备数据库的操作能力
    • Schema.Type:是由Mongoose内定的一些数据类型,基本数据类型都在其中,他也内置了一些Mongoose特有的Schema.Type。当然,你也可以自定义Schema.Type,只有满足Schema.Type的类型才能定义在Schema内。NodeJS中的基本数据类型都属于Schema.Type,另外Mongoose还定义了自己的类型// 从官网截取过来的,举例:
      var ExampleSchema = new Schema({
      name:String,
      binary:Buffer,
      living:Boolean,
      updated:Date,
      age:Number,
      mixed:Schema.Types.Mixed, //该混合类型等同于nested
      _id:Schema.Types.ObjectId, //主键
      _fk:Schema.Types.ObjectId, //外键
      array:[],
      arrOfString:[String],
      arrOfNumber:[Number],
      arrOfDate:[Date],
      arrOfBuffer:[Buffer],
      arrOfBoolean:[Boolean],
      arrOfMixed:[Schema.Types.Mixed],
      arrOfObjectId:[Schema.Types.ObjectId]
      nested:{
      stuff:String,
      }
      });
  • Model: 由Schema发布生成的模型,具有抽象属性和行为的数据库操作对
  • Entity: 由Model创建的实体,他的操作也会影响数据

Schema生成Model,Model创造Entity,Model和Entity都可对数据库操作造成影响,但Model比Entity更具操作性

2. node-mongoose安装

npm install mongoose

3. 连接mongoose

创建一个文件db.js:

const mongoose = require('mongoose'),
      DB_URL = 'mongodb://localhost:27017/test';
// 若有密码,则url:mongodb://username:password@host:port/database?options...'
// 连接
mongoose.connect(DB_URL);

// 连接成功
mongoose.connection.on('connected', function () {    
    console.log('Mongoose connection open to ' + DB_URL);  
});

// 连接异常
mongoose.connection.on('error',function (err) {    
    console.log('Mongoose connection error: ' + err);  
});

// 连接断开
mongoose.connection.on('disconnected', function () {    
    console.log('Mongoose connection disconnected');  
});

module.exports = mongoose;

4. mongoose使用

举例,创建了一个用户登录信息表,对此数据进行增删改查
1. 创建文件user.js, 创建Schema,Model

const mongoose = require('./db.js'),
            Schema = mongoose.Schema;

    const UserSchema = new Schema({
        username : { type: String, index: true },                //用户账号
        userpwd: { type: String, required: true },               //密码
        userage: {type: Number, min: 18, max 80 },               //年龄
        logindate : { type: Date, default: new Date()},          //最近登录时间
        city:{ type:'String', enum:['北京','上海'] },             // 城市
        other:{
            type:'String',
            validate:[validator,err]  //validator是一个验证函数,err是验证失败的错误信息
        }
    });
    module.exports = mongoose.model('User',UserSchema);

上面有提到几个定义
- 索引和默认值,即 index和default
- 验证器,即
- required 非空验证
- min/max 范围验证(边值验证)
- enum/match 枚举验证/匹配验证
- validate 自定义验证规则


  1. 进行数据库操作

a. 插入

const User = require("./user.js");
function insert() {
    const user = new User({
        username : 'zhangsan',
        userpwd: 'abcd',
        userage: 37,
        logindate : new Date()
    });

    user.save(function (err, res) {
        if (err) {
            console.log("Error:" + err);
        }
        else {
            console.log("Res:" + res);
        }
    });
}
insert();



b. 修改

const User = require("./user.js");
function update(){
    const wherestr = {'username' : 'zhangsan McGrady'};
    const updatestr = {'userpwd': 'zzzz'};

User.update(wherestr, updatestr, function(err, res){
    if (err) {
        console.log("Error:" + err);
    }
    else {
        console.log("Res:" + res);
    }
})

}
update();

修改器和更新器:
为了更快进行更新的操作。在update中需要写很多选择器

    $inc增减修改器,只对数字有效.下面的实例: 找到 age=22的文档,修改文档的age值自增1
    Model.update({‘age’:22}, {‘$inc’:{‘age’:1} } );
    执行后: age=23

    $set指定一个键的值,这个键不存在就创建它.可以是任何MondoDB支持的类型
    Model.update({‘age’:22}, {‘$set’:{‘age’:’haha’} } );
    执行后: age=’haha’

    $unset同上取反,删除一个键
    Model.update({‘age’:22}, {‘$unset’:{‘age’:’haha’} } );
    执行后: age键不存在

    $push给一个键push一个数组成员,键不存在会创建
    Model.update({‘age’:22}, {‘$push’:{‘array’:10} } );
    执行后: 增加一个 array 键,类型为数组, 有一个成员 10

    $addToSet向数组中添加一个元素,如果存在就不添加
    Model.update({‘age’:22}, {‘$addToSet’:{‘array’:10} } );
    执行后: array中有10所以不会添加

    $each遍历数组, 和 $push 修改器配合可以插入多个值
    Model.update({‘age’:22}, {‘$push’:{‘array’:{‘$each’: [1,2,3,4,5]}} } );
    执行后: array : [10,1,2,3,4,5]

    $pop向数组中尾部删除一个元素
    Model.update({‘age’:22}, {‘$pop’:{‘array’:1} } );
    执行后: array : [10,1,2,3,4] tips: 将1改成-1可以删除数组首部元素

    $pull向数组中删除指定元素
    Model.update({‘age’:22}, {‘$pull’:{‘array’:10} } );
    执行后: array : [1,2,3,4] 匹配到array中的10后将其删除

c. 删除

const User = require("./user.js");
function del(){
    const wherestr = {'username' : 'zhangsan'};

    User.remove(wherestr, function(err, res){
        if (err) {
            console.log("Error:" + err);
        }
        else {
            console.log("Res:" + res);
        }
    })
}
del();

另外,删除和更新的其他方法,常用方法有:
Model.findByIdAndUpdate(id, [update], [options], [callback]) // 找到指定id记录并更新
Model.findOneAndUpdate([conditions], [update], [options], [callback]) // 找到一条记录并更新
Model.findByIdAndRemove(id, [options], [callback]) // 找到指定id记录并删除
Model.findOneAndRemove(conditions, [options], [callback]) // 找到一条记录并删除

const User = require("./user.js");
    function findByIdAndUpdate(){
        const id = '56f2558b2dd74855a345edb2';
        cibst updatestr = {'userpwd': 'abcd'};
        User.findByIdAndUpdate(id, updatestr, function(err, res){
            if (err) {
                console.log("Error:" + err);
            }
            else {
                console.log("Res:" + res);
            }
        })
    }
    findByIdAndUpdate();
  • d. 查询
    查询有直接查询和链式查询,链式查询只有在执行exec方法时才执行查询,而且必须有回调
  • 条件查询
    Model.find(conditions, [fields], [options], [callback])
    //fields和options是可选参数, field的值中,1为包括,0为不包括,options: 选项参数
    //fields: 参数用于字段映射,默认情况下,MongoDB会返回匹配文档的所有字段,使用映射(projection)设置希望返回的字段,用于取文档字段的子集,相当于SQL中SELECT后面我们需要的字段
    • User.find({'username' : 'zhangsn'}, {"username": 1 ,"_id": 0}, callback); // 输出只会有username字段,设置方法如上,1表示查询输出该字段,0表示不输出
    • User.find({userage: {$gte: 21, $lte: 65}}, callback); // 这表示查询年龄大于等21而且小于等于65岁
      参数还有:
      $or    或关系
        $nor    或关系取反
        $gt    大于
        $gte    大于等于
        $lt     小于
        $lte    小于等于
        $ne 不等于
        $in 在多个值范围内
        $nin 不在多个值范围内
        $all 匹配数组中多个值
        $regex  正则,用于模糊查询
        $size   匹配数组大小
        $maxDistance  范围查询,距离(基于LBS)
        $mod   取模运算
        $near   邻域查询,查询附近的位置(基于LBS)
        $exists   字段是否存在
        $elemMatch  匹配内数组内的元素
        $within  范围查询(基于LBS)
        $box    范围查询,矩形范围(基于LBS)
        $center 范围醒询,圆形范围(基于LBS)
        $centerSphere  范围查询,球形范围(基于LBS)
        $slice    查询字段集合中的元素(比如从第几个之后,第N到第M个元素
      * User.find({'username':{$regex:/m/i}}, [callback]) // 模糊查询,正则匹配有'm'的名字,且不区分大小写
  • 数量查询
    Model.count(conditions, [callback]) // res结果会输出数量,也可以传入条件做条件查询。
  • 根据id查询
    Model.findById(id, [fields], [options], [callback]) // 要据ID得到数据
  • 分页查询
const User = require("./user.js");
function getByPager(){           
    const pageSize = 5;                   //一页多少条
    const currentPage = 1;                //当前第几页
    const sort = {'logindate':-1};        //排序(按登录时间倒序)
    const condition = {};                 //条件
    const skipnum = (currentPage - 1) * pageSize;   //跳过数

    User.find(condition).skip(skipnum).limit(pageSize).sort(sort).exec(function (err, res) {
        if (err) {
            console.log("Error:" + err);
        }
        else {
            console.log("Res:" + res);
        }
    })
}
getByPager();



  • e. aggregate
    在MongoDB中,聚合(aggregate)主要用于进行处理数据,比如统计求和,求平均数等,并返回计算后的数据结果,这给我们带来了很多便捷之处,因为可以在读取数据的同时进行数据处理
    例如:
    // $match用于获取年龄大于20小于或等于40记录,然后将符合条件的记录送到下一阶段$group管道操作符进行处理。
    User.aggregate([
    { $match : { userage : { $gt : 20, $lte : 40 } } },
    { $group: { _id: null, count: { $sum: 1 } } }
    ]);

下面列举一些:
$project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
$match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
$limit:用来限制MongoDB聚合管道返回的文档数。
$skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
$unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
$group:将集合中的文档分组,可用于统计结果。
$sort:将输入文档排序后输出。
$geoNear:输出接近某一地理位置的有序文档。

更多参数可以参考下方参考链接。

8. 其他

注意:
- 表”应该描述为“collection(集合)”;“行”应该描述为“文档(document)”,一个database中可以有多个collection,一个collection中又可以有多个document
- 用CMD中使用mongo.exe操作时,插入中文遇一了问题,原因是MongoDB默认编辑是utf-8,而CMD是GBK,所以在CMD窗口中执行这个命令修改编辑即可:chcp 65001
- 注意mongodb严格区分大小写,比如查询 db.tb2.find({"name":"wilson0"})和 db.tb2.find({"Name":"wilson0"}) 并不是用的同一字段做的条件;

参考:
mongodb: docs.mongodb.com/manual
mongodb查询参数: mongodb-documentation.readthedocs.io
mongoose: mongoosejs.com/docs/api
blog:
cnblogs.com/zhongweiv/p
cnodejs.org/topic/504b4

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31537575/viewspace-3154669/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2018-05-16

  • 博文量
    4259
  • 访问量
    39983