freeCodeCamp 旅途21 - MongoDB 和 Mongoose

MongoDB 和 Mongoose

MongoDB 是一个用来存储应用数据的数据库。Mongo 是一个非关系,“NoSQL” 的数据库。也就是说 Mongo 在一个记录里存储所有的数据,而不是像关系数据库那样存储在多个预设的表中。这种存储结构有很多好处:

  • 可扩展:一般来讲,非关系型数据库可以分布式存储在不同的操作系统间。这意味着它可以以低成本方便的提高性能。
  • 灵活:新的数据集和属性可以直接添加进文档而无需更改表。
  • 可复制:可以并行拷贝数据,如果数据损坏了,备份也可以成为主数据源。

Mongo 支持 JSON 形式的指令查询,所以它是学习 JavaScript 后端的不二选择。因为通过它访问文档或者属性可以像访问 JavaScript 的对象一样方便。

Install and Set Up Mongoose

在 package.json 文件中添加 MongoDB 和 Mongoose 依赖,将 mLab 数据库的 URI 作为 MONGO_URI 变量存储在私有 .env 文件中。然后require('mongoose'),使用mongoose.connect()命令来连接数据库。

// 第一种方式
var mongoose = require("mongoose");
var mongodb = require("mongodb");
mongoose.connect(process.env.MONGO_URI);

// 第二种方式
var mongoose = require("mongoose");
var mongodb = require("mongodb");
var MongoClient = require('mongodb').MongoClient;
var client = new MongoClient(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true });
client.connect(function(err){
  var collection = client.db("test").collection("devices");
   // perform actions on te collection object
  client.close();
})

Create a Model

我们需要一个 Schema,每一个 Schema 对应一个 MongoDB collection,并且在那个 collection 里面定义 documents 的模型。

Schemas 是 Models 的构建块。它们可以嵌套来创建复杂的模型。

Model 可以被实例化,实例化后的对象称为 documents。

创建一个拥有以下 Prototype 的 Person 对象:

- Person Prototype -
name : string [required]
age : number
favoriteFoods : array of strings (*)

你可以使用基础的 SchemaTypes 去添加更多的字段,比如使用 required 或者 unique 这样的简单验证去设置默认值。参考 Mongoose 文档。

注意: Glitch 是一个真实的服务,并且通过 handler 函数和 db 进行交互。 这些函数通过一些事件去触发(例如:有人从终端调用了你的 API),我们在这些练习中遵循同样的方法。 比如,我们在完成 nserting、searching、updating 或者 deleting 这样的异步操作后接着回调done()函数。它遵循 Node 的惯例,需要在 success 时回调done(null, data),在 error 时回调done(err)

Warning - 当与远程服务器交互时可能发生错误!

/* 示例 */
var someFunc = function(done) {
  // 执行一些可能产生错误的代码
  if(error) return done(error);
  done(null, result);
};

Create and Save a Record of a Model

使用 Person 的 constructor(构造器)函数可以创建一个 document 对象,该对象包含nameagefavoriteFoods字段。这些字段的类型必须符合 Person Schema 里面定义的类型。然后调用document.save()。使用 Node 惯例传递 callback。通常情况下,所有的 CRUD(增查改删)方法都会像下面一样作为最后一个参数去执行一个callback()

/* 示例 */
person.save(function(err, data) {
  // 你的代码
});
var tiffany = new Person({name: "tiffany", age: 28, favoriteFoods: ["apple", "raspberry", "banana"]});
tiffany.save(function(err, tiffany){
  if(err) {
    return console.error(err);
  }
  console.log(tiffany);
});

Create Many Records with model.create()

有时你需要创建很多的 model 实例。例如:在使用初始数据为数据库初始化时,Model.create()接受一组像[{name:'John', ...}, {...}, ...]的数组作为第一个参数,并将其保存到数据库。使用arrayOfPeople作为Model.create()的参数创建很多个 people 实例。

var arrayOfPeople = [{ name: 'jelly bean' }, { name: 'snickers' }];
Person.create(arrayOfPeople, function(err, persons){
  if(err){
    return console.error(err);
  }
  var jellybean = persons[0];
  var snickers = persons[1]; 
})

Use model.find() to Search Your Database

使用Model.find() -> [Person]来查询给定名称的所有的人。最简单的用法:Model.find()接受一个查询的 document(一个 JSON 对象)作为第一参数,然后是回调。它将返回匹配到的项目组成的数组。这个支持极其广泛的搜索选项。使用人名作为搜索的关键词,来校验它。

Person.find({name: 'jelly bean'}, function (err, docs) {
  if(err){
    return console.error(err);
  }
});

Use model.findOne() to Return a Single Matching Document from Your Database

Model.findOne()表现像Model.find(),但是它仅仅返回一个 document(而不是一个数组),即使数据库里有很多条 item(项目)。当你按声明成unique的属性进行搜索时,Model.findOne()尤其有用。

Person.findOne({avoriteFoods: ["apple"]}, function (err, adventure) {
  if(err){
    return console.error(err);
  }
});

Use model.findById() to Search Your Database By _id

当我们保存一个 document, MongoDB 自动添加 _id 字段,并给该字段设置 unique(唯一)属性。通过 _id 搜索是一个非常频繁的操作,所以 Mongose 为它提供了一个专门的方法。

Person.findById('123', function (err, doc) {
  if (err) return console.error(err);
  // doc.name = 'jason bourne';
  // doc.save(callback);
});

Perform Classic Updates by Running Find, Edit, then Save

传统应用里,如果你想要编辑 document,然后在某处使用它。你就必须在服务器响应中将其返回。Mongoose 有一个专用的更新方法:Model.update() , 它与低级的 mongo 驱动绑定,可以批量编辑符合特定条件的多个 document,而不用返回更新后的 document,取而代之返回'状态'消息。此外,它使模型校验变得更棘手,因为它是直接调用了 mongo 的驱动程序。

Person.update({ name: 'Tobi' }, { ferret: true }, { multi: true }, function (err, raw) {
  if (err) return console.log(err);
  console.log('The raw response from Mongo was ', raw);
});

Perform New Updates on a Document Using model.findOneAndUpdate()

mongoose 的最新版本简化了 documents 的更新。 但是一些高级的用法 (比如 pre/post 钩子, 验证) 更复杂, 所以老方法更常用。当通过 Id 进行搜索时还可以使用 findByIdAndUpdate()

A.findByIdAndUpdate(id, update, options, callback) // executes
A.findByIdAndUpdate(id, update, options)  // returns Query
A.findByIdAndUpdate(id, update, callback) // executes
A.findByIdAndUpdate(id, update)           // returns Query
A.findByIdAndUpdate()   

Person.findByIdAndUpdate('213', { $set: { name: 'jason bourne' }}, function (err, doc) {
  if (err) return console.error(err);
  // doc.name = 'jason bourne';
  // doc.save(callback);
})

Delete One Document Using model.findByIdAndRemove

使用 findByIdAndRemove()或者 findOneAndRemove()方法, 通过 _id 删除一个人员。

A.findByIdAndRemove(id, options, callback) // executes
A.findByIdAndRemove(id, options)  // return Query
A.findByIdAndRemove(id, callback) // executes
A.findByIdAndRemove(id) // returns Query
A.findByIdAndRemove()           // returns Query

Person.findByIdAndRemove('245', function (err, doc) {
  if (err) return console.error(err);
  // doc.name = 'jason bourne';
  // doc.save(callback);
})

Delete Many Documents with model.remove()

Model.remove()可用于删除与给定条件匹配的所有 document。 如果想要删除所有叫 “Mary” 的人, 可以使用 Model.remove()

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

Chain Search Query Helpers to Narrow Search Results

如果不给 Model.find()(或者别的搜索方法)传递回调函数,作为的最后一个参数, 则不执行查询。你可以将查询存储在变量中供以后使用,这类对象可以使用链接语法构建查询。 当你最终链接 .exec()方法时,将执行实际的数据库操作。最后将回调传递给 exec()方法。 有很多的查询助手, 这里我们使用最 '著名' 的一种。

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

query.sort('field -test');
query.limit(20)
T.find().select('-x').exec(callback);

ps: 这篇文章很多不全的,有时间再扩展。

你可能感兴趣的:(freeCodeCamp 旅途21 - MongoDB 和 Mongoose)