Node.js_使用 mongoose 連接 MongoDB 數(shù)據(jù)庫

MongoDB 數(shù)據(jù)庫

MongoDB 的數(shù)據(jù)邏輯結(jié)構(gòu):文檔(document)、集合(collection)、數(shù)據(jù)庫(database)。

  • 文檔(document):由鍵值對(duì)構(gòu)成,相當(dāng)于關(guān)系數(shù)據(jù)庫中的一行記錄。
  • 集合(collection):多個(gè)文檔組成一個(gè)集合,相當(dāng)于關(guān)系數(shù)據(jù)庫的表。
  • 數(shù)據(jù)庫(database):多個(gè)集合邏輯上組織在一起,就是數(shù)據(jù)庫。

一個(gè) MongoDB 實(shí)例支持多個(gè)數(shù)據(jù)庫(database)。

MongoDB 數(shù)據(jù)庫結(jié)構(gòu)

使用 mongoose 連接 MongoDB

MongoDB 數(shù)據(jù)庫基礎(chǔ):

  • mongoose 中的一切由 schema(?skēm?) 開始。 schema 是一種以文件形式存儲(chǔ)的數(shù)據(jù)庫模型骨架,并不具備數(shù)據(jù)庫的操作能力。
  • Schema 定義了 model 中的所有屬性,而 model 則是對(duì)應(yīng)一個(gè) MongoDB 中的 collection

Schema 生成 Model,Model 創(chuàng)造 Entity,ModelEntity 都可對(duì)數(shù)據(jù)庫操作造成影響,但 ModelEntity 更具操作性。

連接數(shù)據(jù)庫

連接數(shù)據(jù)庫,實(shí)現(xiàn)增、刪、改、查操作

// 引入 mongoose 模塊
const mongoose = require('mongoose');

// 定義數(shù)據(jù)庫地址
// uri:mongodb://+[用戶名:密碼@]+數(shù)據(jù)庫地址[:端口]+數(shù)據(jù)庫名
// uri:mongodb://user:pass@localhost:port/database
const uri = 'mongodb://user:pass@localhost:port/database?authSource=admin';

// 連接 mongoDB 數(shù)據(jù)庫
mongoose.connect(uri, {useNewUrlParser: true});
const db = mongoose.connection;

// 將連接綁定到錯(cuò)誤事件
db.on('error', console.error.bind(console, 'MongoDB connection error'));

// 錯(cuò)誤事件,同上
db.on('error', function(error) {
  console.error.bind(console, '數(shù)據(jù)庫連接失?。? + error);
});

// 一次打開事件
db.once('open', function() {
    console.log('一次打開記錄');
});

// 數(shù)據(jù)庫連接成功
db.on('open', function() {
  console.log('數(shù)據(jù)庫連接成功');
});

// 數(shù)據(jù)庫連接失敗
db.on('disconnected', function() {
  console.log('數(shù)據(jù)庫連接斷開');
});

// 斷開連接
mongoose.disconnect();

Schema

// 定義 Schema
const Schema = mongoose.Schema;
// 使用 Schema 構(gòu)造函數(shù),創(chuàng)建一個(gè)新的 Schema 實(shí)例
// 實(shí)例化 mongoose.Schema 對(duì)象并定義 Model 的屬性
const ArticleScheme = new Schema({
    title: String,
    author: String,
    content: String,
    publishTime: Date
});
// 將 Schema 注冊(cè)成 Model
mongoose.model('Article', ArticleScheme);

// 如果 Model成功注冊(cè),就可以通過如下方式訪問模型
const ArticleModel = mongoose.model('Article');

// 通過 Model 定義 Entity
var ArticleEntity = new ArticleModel({
    title: 'node.js',
    author: 'node',
    content: 'node.js is great!',
    publishTime: new Date()
});

// 【將文檔插入到集合中】
ArticleEntity.save(function(err) {
    if (err) {
        console.log('save failed ' + err);
    }else {
        console.log('save successed');
    }
});

// 【查詢】
// find() 方法,查詢所有符合要求的數(shù)據(jù)
// findOne() 方法,查詢符號(hào)要求的第一條數(shù)據(jù)
ArticleModel.find({title:'node.js'}, function(err, docs) {
    if (err) {
        console.log('error');
        return;
    }
    console.log('result: ' + docs); // 打印實(shí)體
    
    // 【查詢紀(jì)錄后,修改記錄的值】
    docs[0].title = 'javascript'; // 修改數(shù)據(jù)
    docs[0].save(); // 保存修改后的數(shù)據(jù)

    // 【刪除數(shù)據(jù)】
    if (docs) {
        // 遍歷文檔,逐條刪除
        docs.forEach(function(ele) {
            // 只有單個(gè)文檔可以使用 remove() 方法
            ele.remove();
        })
    }
})

可以將 Model 提取成單獨(dú)的一個(gè)類:

??

強(qiáng)烈建議在每個(gè)模型模塊(文件)中,定義每個(gè)模型綱要,導(dǎo)出方法以創(chuàng)建模型。

article.js

// 導(dǎo)入 mongoose 模塊
const mongoose = require('mongoose');

// 定義 Schema
const Schema = mongoose.Schema;
const ObjectId = Schema.ObjectId; // 主鍵

const ArticleSchema = new Schema({
    id: ObjectId,
    title: {type: String, required: true, max: 100},
    name: {type: String, required: true, max: 100},
    date: {type: date}
});

// 導(dǎo)出模型
module.exports = mongoose.model('Article', ArticleSchema);

farmers.js

const mongoose = require('mongoose');

// 定義 Schema
const Schema = mongoose.Schema;
const FarmerSchema = new Schema({
  uuid: { type: String, required: true },
  name: { type: String, required: true },
  id_number: { type: String, required: true },
  phone: { type: String, required: true },
  public_key: { type: String, required: true },
  private_key: { type: String, required: true },
});

// 導(dǎo)出模型
module.exports = mongoose.model('Farmer', FarmerSchema);

// --------
// 引入并使用
const FarmerModel = require('../model/farmers');

增(Create)

通常所說的 CRUD 就是數(shù)據(jù)庫的增(Create)刪(Delete)查(Read)改(Update)。

Model.create()

const doc = ({
  uuid: '1234567890',
  name: '張三',
  id_number: '320321201810104321',
  phone: '15812345678',
  public_key: 'publickey',
  private_key: 'privatekey',
});

FarmerModel.create(doc, function(err, docs) {
  if (err) {
    console.log('create error: ' + err);
    return;
  }
  console.log('create success:\n ' + docs);
});

Entity.save()

// 通過 Model 定義 Entity
const FarmerEntity = new FarmerModel({
  uuid: '2234567890',
  name: '李四',
  id_number: '320321201810104322',
  phone: '15912345678',
  public_key: 'publickey_1',
  private_key: 'privatekey_1',
});

// 將 Entity 保存到數(shù)據(jù)庫
FarmerEntity.save(function(err, docs) {
  if (err) {
    console.log('create error: ' + err);
  }
  console.log('create success:\n ' + docs);
});

Model.insertMany(),一次插入多個(gè)值

// insertMany()
FarmerModel.insertMany([{
  uuid: '12345',
  name: '王五',
  id_number: '123456',
  phone: '123456',
  public_key: '12345',
  private_key: '12345',
}, {
  uuid: '12345',
  name: '趙六',
  id_number: '123456',
  phone: '123456',
  public_key: '12345',
  private_key: '12345',
}], function(err, docs) {
  if (err) {
    console.log('create error: ' + err);
  }
  console.log('create success:\n ' + docs);
});

查(Read)

Model.find(),查詢所有符合要求的數(shù)據(jù)

FarmerModel.find({ name: '張三' }, function(err, docs) {
  if (err) {
    console.log('查詢錯(cuò)誤' + err);
    return;
  }
  console.log('打印實(shí)體:result: ' + docs);
});

// 從集合/表中按照 uuid 鍵值對(duì)查找文檔(document)
db.getCollection('NaturalPersonInfo').find({uuid:'8a033c7f20ea2bdea3c4b9d60d42f11e'})

Model.findOne(),查詢符號(hào)要求的第一條數(shù)據(jù)

Model.findById()

改(Update)

Model.update()

// Model.update()
// 查詢 uuid 為 2234567890 的實(shí)體,將他的名字改為張團(tuán)團(tuán),允許更新多條查詢記錄
FarmerModel.update({ uuid: '2234567890' }, { name: '張團(tuán)團(tuán)' }, { multi: true }, function(err, docs) {
  if (err) {
    console.log('更新錯(cuò)誤' + err);
    return;
  }
  console.log('更新后的實(shí)體:result: ' + docs);
});

Model.updateMany(),一次更新多條數(shù)據(jù)。

Model.updateOne(),一次更新一條數(shù)據(jù)。

Model.findByIdAndyUpdate(),

Model.findOneAndUpdate()

刪(Delete)

Model.remove(),刪除

FarmerModel.remove({ uuid: '1234567890' }, function(err, docs) {
  if (err) {
    console.log('查詢錯(cuò)誤' + err);
    return;
  }
  console.log('刪除成功');
});

Model.findByIdAndRemove()

Model.findOneAndRemove()

常見錯(cuò)誤

1. 連接 MongdDB 數(shù)據(jù)庫時(shí)提示字符串參數(shù)失效

示例代碼:

// 連接 mongoDB 數(shù)據(jù)庫
mongoose.connect(uri, function(err) {
    if (err) {
        console.log('connect failed' + err);
        return;
    }
    console.log('connect success');
});

錯(cuò)誤提示內(nèi)容:

DeprecationWarning: current URL string parser is deprecated, and will be removed in a future version. To use the new parser, pass option { useNewUrlParser: true } to MongoClient.connect.

解決方法:連接時(shí)傳遞參數(shù):

// 連接 mongoDB 數(shù)據(jù)庫
mongoose.connect(uri, {useNewUrlParser: true}); // <——
const db = mongoose.connection;
// 將連接綁定到錯(cuò)誤事件
db.on('error', console.error.bind(console, 'MongoDB connection error'));

2. 連接 MongoDB 數(shù)據(jù)庫時(shí)授權(quán)失敗,提示:errmsg: 'Authentication failed.', code: 18

// uri 后面添加 authDatabase 參數(shù)
mongoose.connect('mongodb://user:password@host:port/dbname?authSource=admin')

解決參考:Authentication in mongoose using SCRAM-SHA-1

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容