大前端之路node第(3)天:mongodb資料庫工具之Mongoose
mongoDB簡介:
mongoDB與一些關係型資料庫相比,它更顯得輕巧、靈活,非常適合在資料規模很大、事務性不強的場合下使用。同時它也是一個物件資料庫,沒有表、行等概念,也沒有固定的模式和結構,所有的資料以文件的形式儲存。
·由c++語言編寫,是一個分散式檔案儲存的開源NoSQL資料庫系統。在高負載的情況下,新增更多的節點,可以保證伺服器效能。
· mongoDB旨在為web應用提供可擴充套件的高效能資料儲存解決方案
· mongoDB將資料儲存為一個文件,資料結構由鍵值對組成。mongoDB文件類似於JSON物件,欄位值可以包含其他文件、陣列及文件陣列。
安裝 https:www.mongodb.org/download下載安裝包
安裝視覺化工具,如robomongo、mongovue等
mongodb的啟動與連線
- windows啟動伺服器端 找到mongodb的安裝目錄(比如是D:\mongodb),shift+右鍵開啟命令視窗,新建一個data資料夾,在命令列中輸入
mongod --dbpath=D:\mongodb\data
如果出現connections on port 27017就表示啟動成功並在27017埠上監聽了客戶端的請求。--dbpath後的值表示資料庫檔案的儲存路徑,而且後面的路徑必須事先建立好,必須已經存在,否則服務開啟失敗。另外,這個命令窗體一旦關閉就相當於停止了mongodb的服務。
- 啟動客戶端連線伺服器 找到mongodb的安裝目錄,比如D:\mongodb\bin,在該目錄下開啟命令列視窗,輸入mongo --host=127.0.0.1或者mongo,按回車鍵,其中--host後的值表示伺服器的ip地址,127.0.0.1表示的是本地伺服器,每次資料庫都會預設連線test資料庫
mongodb基本概念
·資料庫
1,一個mongoDB可以建立多個數據庫
2,mongoDB的單個例項可以容納多個獨立的資料庫,每一個都有自己的集合和許可權,不同的資料庫也放置在不同的檔案中。
3,資料庫也通過名字來標識,資料庫名可以是滿足一下條件的任意utf8字串
- 不能是空字串
- 不能含有空格、.、$、/、\和\0(空字元)
- 應全部小寫
- 最多64位元組
4, 有一些資料庫名是保留的,可以直接訪問這些有特殊作用的資料庫
- admin:’root‘資料庫,要是將一個使用者新增到這個資料庫,這個使用者自動繼承所有資料庫的許可權,一些特定的伺服器端命令也只能從這個資料庫執行,比如列出所有的資料庫或者關閉伺服器
- local:這個資料庫永遠不會被複制,可以用來儲存於本地單臺伺服器的任意集合
- config:當mongoDB用於分片設定時,config資料庫在內部使用,用於儲存分片的相關資訊
·文件(相當於row)
文件是mongoDB中的核心單元,可以將文件類比成關係資料庫中的每一行資料。多個鍵及其關聯的值有序的放置在一起就是文件。mongoDB使用了BSON這種結構來儲存資料和網路資料交換。BSON資料可以理解為在JSON的基礎上添加了一些json中沒有的資料型別。
·集合(相當於table)
集合就是一組文件的組合,如果將文件類比成資料庫中的行,那麼集合就可以類比成資料庫的表。在mongoDB中的集合是無模式的,也就是說集合中儲存的文件的結構可以是不同的,比如下面的兩個文件可以同時存入到一個集合中
{"name":"lucy"}{"Name":"lily","sex":"女"} 注:當第一個文件插入時,集合就會被建立
·欄位field(相當於column)
對mongoDB的基礎操作
資料庫的方法 help
·建立資料庫 use database_name 注:如果資料庫不存在,則建立資料庫,否則切換到指定資料庫
·檢視所有資料庫 show dbs 注:如果新建一個數據庫沒有顯示,則需要向新建的資料庫插入一些資料db.collection_name.insert({name:'zhangsan'})
·檢視當前使用的資料庫 db或db.getName() 注:db代表的是當前資料庫
·刪除資料庫 db.dropDatabase()
·斷開mongodb與mongodb服務的連線 exit
操作集合方法 db.worker.help()檢視幫助api
·檢視當前資料庫下有哪些集合 show collections
·建立集合 db.createCollection("collection_name")
·向集合中插入文件 db.collection_name.insert(document) 注:document指要插入的文件
·檢視集合中有多少條document資料 db.collection_name.count()
·刪除當前資料庫中的集合 db.collection_name.drop()
文件的方法
·插入文件 db.collection_name.insert(document) 插入文件後會自動生成一個_id號,_id的型別是ObjectId型別的
也可以用陣列的方式一次向集合中插入多條文件db.collection_name.insert([document1,document2])
·查詢集合中的所有文件 db.collection_name find()
·使用save方法插入文件(插入或者更新),_id如果存在就更新,_id如果不存在就插入。用法與insert類似
·更新已經存在的文件 db.collection_name.update(<query>,<update>,{upsert:<boolean>,multi:<boolean>,writeConcern:<document>})
- query:update的查詢條件,類似sql update查詢的where後面的
- update:update的物件和一些更新的操作符(如$set,$inc...),$inc在原基礎上累加後更新,$set直接更新
- multi:可選,預設false,只更新找到的第一條記錄;如果為true,就把按條件查出來的多條記錄全部更新
eg: db.worker.update({name:'zhangsan'},{$set:{name:'zhangsan123'}})
擴充套件
儲存在mongodb集合中的每個文件都有一個預設的主鍵_id,這個主鍵名稱是固定的,它可以是mongodb支援的任何資料型別,預設是ObjectId。該型別的值由系統自己生成,從某種意義上說不會重複。mysql等關係型資料庫的主鍵都是自增的。但在分散式環境下,這種方法不可行,會產生衝突。因此,mongoDB採用ObjectId的型別來做主鍵。Objectid是一個12位元組的BSON型別字串。
Mongoose
mongoose是mongoDB的一個物件模型工具,是基於node-mongodb-native開發的mongoDB的nodejs驅動,可以在非同步的環境下執行。同時它也是針對mongoDB操作的一個物件模型庫,封裝了mongoDB對文件的一些增刪改查等常用方法,讓nodejs操作mongoDB資料庫變得更加容易。
安裝Mongoose:
//引入mongoose
var mongoose = require('mongoose');
//連線
mongoose.connect('mongodb://localhost/anyao', { useNewUrlParser: true }, function(err) {
if (err) {
console.log('Connection Error:' + err);
} else {
console.log('Connection success!');
}
});
//監聽斷開
mongoose.connection.on("disconnected", function(){
console.log("資料庫斷開");
});
更多鉤子移步官方文件
Mongoose核心概念
模式:
//建立模式 -->理解為建表的表頭 不過這有帶有屬性描述的
var animalSchema = new Schema({ name: String, type: String });
/* 允許使用的SchemaTypes:
String
Number
Date
Buffer
Boolean
Mixed
ObjectId
Array */
//利用上面的表頭例項化一個表出來,並且名字為Animas(預設會為你加s)
var Animal = mongoose.model('Anima', animalSchema);
//為我們的模式新增一個靜態方法
animalSchema.statics.findByName = function(name, cb) {
return this.find({
$or : [ //多條件,陣列
{name : {$regex : name}},
{name1 : {$regex : name}}
]
},{"_id":0,"__v":0,}, cb);
};
//使用該靜態方法
Animal.findByName(req.query.name, function(err, animals) {
console.log(animals);
let obj = {
success: '請求成功',
data: animals
};
res.send(JSON.stringify(obj));
});
// 例項方法 define a schema-->找出一些特殊的資料給這些例項新增方法
var animalSchema = new Schema({ name: String, type: String });
// assign a function to the "methods" object of our animalSchema
animalSchema.methods.findSimilarTypes = function(cb) {
return this.model('Animal').find({ type: this.type }, cb);
};
//現在我們所有的animal的例項有一個findsimilartypes方法可用。
var Animal = mongoose.model('Animal', animalSchema);
var dog = new Animal({ type: 'dog' });
dog.findSimilarTypes(function(err, dogs) {
console.log(dogs); // woof
});
還有一些 查詢助手 、查詢助手 、虛擬屬性等都比較簡單官網看一下即可
接下來看第二個引數options:
其實就是內部給咱們封裝好的一些便利條件,比如倒敘,去除某項等
//選項(Options):
new Schema({..}, options);
// or
var schema = new Schema({..});
schema.set(option, value);
options的選項大致有:
- autoIndex
- capped
- collection
- emitIndexErrors
- id
- _id
- minimize
- read
- safe
- shardKey
- strict
- toJSON
- toObject
- typeKey
- validateBeforeSave
- versionKey
- skipVersioning
- timestamp
模式瞭解過了就可以愉快的crud了、
新增資料
// 方法 1
var personEntity = new personModel(obj);
personEntity.save(function (err) {
if (err) {
console.log('insert failed');
} else {
console.log('insert success');
}
});
// 方法 2
personModel.create(obj, function (err) {
if (err) {
console.log('insert failed');
} else {
console.log('insert success');
}
});
修改操作
// 方法 1
personModel.update({_phone: 222}, {$set: {_name: '把222的都改了'}}, { multi: true}, function(err){
if (err) { // 錯誤
console.log('update failed');
} else { // 正確
console.log('update success');
}
});
// 方法 2
var id = "56fc1bbe7c2bce52c38fc5f8";
personModel.findById(id, function(err, person){
if (err) {
console.log('update failed');
} else {
person._name = 'from_id';
person.save(function(err){ ... });
console.log('update success');
}
});
查詢資料
直接查詢
personModel.findOne({'_phone': 111}, function (err, person) {
if (err) {
console.log('select failed');
} else {
console.log( person );
}
});
查詢一條
var query = personModel.findOne({'_phone': 111});
query.select();
query.exec(function(err, person){
if (err) {
console.log('select failed');
} else {
console.log(person);
}
});
查詢多條
//第一種
var query = personModel.find({'_phone': 222});
query.select();
query.exec(function(err, person){
if (err) {
console.log('select failed');
} else {
console.log(person);
}
});
//多類別or、這裡只舉一個例子 還有很多已經給出的輔助api
animalSchema.statics.findByName = function(name, cb) {
return this.find({
$or : [ //多條件,陣列
{name : {$regex : name}},
{name1 : {$regex : name}}
]
},{"_id":0,"__v":0,}, cb);
};
鏈式查詢
personModel
.where('_phone')
.where('_name').equals('aaa')
.limit(2)
.select()
.exec(function (err, person) {
if (err) {
console.log('select failed');
} else {
console.log(person);
}
});
另外附詳細鏈式查詢表
personModel //model 物件
.find({ occupation: /host/ }) // 條件
.where('name.last').equals('Ghost') //欄位 = 值
.where('age').gt(17).lt(66) // 範圍
.where('likes').in(['vaporizing', 'talking']) // 範圍
.limit(10) // 查幾條
.skip(20) // 跳過幾條
.asc('age') // 排序
.sort('-occupation')
.slaveOk()
.hint({ age: 1, name: 1 })
.select('name occupation') // 執行查詢 () 中的值可以省略, 只是別名
.exec(callback); // 回撥函式, 處理查詢結果
刪除操作
//刪除邏輯一定要對 小心刪庫跑路。。
var personEntity = new personModel();
let selobg={_id:"56fc281ab64732d8c33b4db7"};
personModel.remove(selobg, function (err) {
if (err) {
console.log('delete failed');
} else {
console.log('detete success');
}
});
到這就可以愉快的建表了、入門了。
相關完整文件:
後面更一些其他操作,操作流檔案與使用第三方外掛等