1. 基础介绍 #

1.1 MongoDB简介 #

MongoDB是一个开源的NoSQL数据库 同时它也是一个对象数据库,没有固定的模式和结构 所有的数据以文档的形式存储,数据格式就是JSON。

1.2 Mongoose是什么? #

Mongoose是MongoDB的一个对象模型工具 同时它也是针对MongoDB操作的一个对象模型库,封装了MongoDB对文档的的一些增删改查等常用方法 让NodeJS操作Mongodb数据库变得更加灵活简单

1.3 安装mongoose #

$ npm install mongoose

1.4 使用mongoose #

var mongoose = require("mongoose");
//mongoose.connect("mongodb://localhost:端口号/数据库名称");
mongoose.connect("mongodb://localhost:27017/zhufengpeixunblog");

1.5 Schema #

Schema是数据库集合的模型骨架 定义了集合中的字段的名称和类型以及默认值等信息

1.5.1 定义Schema #

    var personSchema = new mongoose.Schema({
      name:String, //姓名
      binary:Buffer,//二进制
      living:Boolean,//是否活着
      birthday:Date,//生日
      age:Number,//年龄
      _id:Schema.Types.ObjectId,  //主键
      _fk:Schema.Types.ObjectId,  //外键
      array:[],//数组
      arrOfString:[String],//字符串数组
      arrOfNumber:[Number],//数字数组
      arrOfDate:[Date],//日期数组
      arrOfBuffer:[Buffer],//Buffer数组
      arrOfBoolean:[Boolean],//布尔值数组
      arrOfObjectId:[Schema.Types.ObjectId]//对象ID数组
      nested:{ //内嵌文档
        name:String,
      }
    });

1.6 Model #

Model是由通过Schema构造而成 除了具有Schema定义的数据库骨架以外,还可以操作数据库 如何通过Schema来创建Model呢,如下:

//连接数据库
mongoose.connect("mongodb://127.0.0.1:27017/zfpx");
//两个参数表示定义一个模型
var PersonModel = mongoose.model("Person", PersonSchema);
// 如果该Model已经定义,则可以直接通过名字获取
var PersonModel = mongoose.model('Person');//一个参数表示获取已定义的模型

拥有了Model,我们也就拥有了操作数据库的能力

在数据库中的集合名称等于 模型名转小写再转复数,比如 Person>person>people,Child>child>children

2. 基础操作 #

2.1 查询 #

语法

Model.find(查询条件,callback);

代码

Model.find({},function(error,docs){
  //若没有向find传递参数,默认的是显示所有文档
});

Model.find({ "age": 6 }, function (error, docs) {
  if(error){
    console.log("error :" + error);
  }else{
    console.log(docs); //docs: age为6的所有文档
  }
});

2.2 Model保存 #

语法

Model.create(文档数据, callback))

代码

 PersonModel.create({ name:"zfpx", age:7}, function(error,doc){
    if(error) {
        console.log(error);
    } else {
        console.log(doc);
    }
});

2.3 更新 #

语法

Model.update(查询条件,更新对象,callback);

代码

var conditions = {name : 'zfpx'};
  var update = {$set : { age : 100 }};
  PersonModel.update(conditions, update, function(error){
      if(error) {
          console.log(error);
      } else {
          console.log('Update success!');
        }
    });

请注意如果匹配到多条记录,默认只更新一条,如果要更新匹配到的所有记录的话需要加一个参数 {multi:true}

2.4 删除 #

语法

Model.remove(查询条件,callback);

代码

var conditions = { name: 'zfpx' };
PersonModel.remove(conditions, function(error){
    if(error) {
          console.log(error);
    } else {
        console.log('Delete success!');
    }
});

3. 基本查询 #

3.1 准备数据 #

        PersonModel.create([
                          { name:"zfpx1", age:1 },
                          { name:"zfpx2", age:2 },
                          { name:"zfpx3", age:3 },
                          { name:"zfpx4", age:4 },
                          { name:"zfpx5", age:5 },
                          { name:"zfpx6", age:6},
                          { name:"zfpx7", age:7 },
                          { name:"zfpx8", age:8 },
                          { name:"zfpx9", age:9},
                          { name:"zfpx10",age:10 }
                         ], function(error,docs) {
            if(error) {
                console.log(error);
            } else {
                console.log('save ok');
            }
        });

3.2 属性过滤 #

语法

find(Conditions,field,callback)

代码

//field省略或为Null,则返回所有属性。
//返回只包含name、age两个键的所有记录
Model.find({},{name:1, age:1, _id:0},function(err,docs){
   //docs 查询结果集
})

我们只需要把显示的属性设置为大于零的数就可以,当然1是最好理解的,_id是默认返回,如果不要显示加上("_id":0)

3.3 findOne(查询单条) #

与find相同,但只返回单个文档,也就说当查询到即一个符合条件的数据时,将停止继续查询,并返回查询结果 语法

findOne(Conditions,callback)

代码

TestModel.findOne({ age: 6}, function (err, doc){
       // 查询符合age等于6的第一条数据
       // doc是查询结果
});

3.4 findById(按ID单条数据) #

与findOne相同,但它只接收文档的_id作为参数,返回单个文档 语法

findById(_id, callback)

代码

PersonModel.findById(person._id, function (err, doc){
     //doc 查询结果文档
});

4. 高级查询 #

可以限制结果的数量,跳过部分结果,根据任意键对结果进行各种排序

所有这些选项都要在查询被发送到服务器之前指定

4.1 limit(限制数量) #

在查询操作中,有时数据量会很大,这时我们就需要对返回结果的数量进行限制 那么我们就可以使用limit函数,通过它来限制结果数量。 语法

find(Conditions,fields,options,callback);

代码

Model.find({},null,{limit:20},function(err,docs){
        console.log(docs);
});

如果匹配的结果不到20个,则返回匹配数量的结果,也就是说limit函数指定的是上限而非下限

4.2 skip(跳过/略过的数量) #

skip函数的功能是略过指定数量的匹配结果,返回余下的查询结果 如下示例:

find(Conditions,fields,options,callback);

代码

Model.find({},null,{skip:4},function(err,docs){
        console.log(docs);
});

如果查询结果数量中少于4个的话,则不会返回任何结果。

4.3 sort函数 #

sort函数可以将查询结果数据进行排序操作 该函数的参数是一个或多个键/值对 键代表要排序的键名,值代表排序的方向,1是升序,-1是降序 语法

find(Conditions,fields,options,callback)

代码

 Model.find({},null,{sort:{age:-1}},function(err,docs){
      //查询所有数据,并按照age降序顺序返回数据docs
});

sort函数可根据用户自定义条件有选择性的来进行排序显示数据结果。

4.4 分页查询 #

Model('User').find({})
  .sort({createAt:-1})
  .skip((pageNum-1)*pageSize)
  .limit(pageSize)
  .populate('user')
  .exec(function(err,docs){
     console.log(docs);
  });

4.5 populate #

var mongoose = require('mongoose');
//连接数据库
mongoose.connect('mongodb://localhost:27017/201606blog');
//定义课程Schema
var CourseSchema = new mongoose.Schema({
    name:String
});
var CourseModel = mongoose.model('Course',CourseSchema);
var PersonSchema = new mongoose.Schema({
    name:{
        type:String,
        required:true
    },
    // 外键 别的集合的主键
    course:{
        type:mongoose.Schema.Types.ObjectId,
        ref:'Course' //指明此外键是哪个集合中的外键
    }
});
var PersonModel = mongoose.model('Person',PersonSchema);
CourseModel.create({name:'node.js'},function(err,course){
    PersonModel.create({name:'zfpx',course:course._id},function(err,doc){
        console.log(doc);
        PersonModel.findById(doc._id).populate('course').exec(function(err,doc){
            console.log(doc);
        })
    })
});

5. 扩展阅读 #

mongoose