關鍵詞:mongodb安裝 mongoose使用 robomongo mongoose的CRUD操做 mongoose的查詢,增長,修改,刪除html
MongoDBnode
MongoDB是基於Javascript語言的數據庫,存儲格式是JSON,而Node也是基於JavaScript的環境(庫),因此node和mongoDB的搭配能減小由於數據轉換帶來的時間空間開銷。mysql
Mongoosegit
是MongoDB的一個對象模型工具,它將數據庫中的數據轉換爲JavaScript對象以供你在應用中使用,封裝了MongoDB對文檔的的一些增刪改查等經常使用方法,讓NodeJS操做Mongodb數據庫變得更加靈活簡單。github
Robomongosql
一個可視化的mongoDB操做軟件,相似於mysql的navicat可視化工具。mongodb
捋一捋它們的關係,mongoDB是一個數據庫,mongoose是你在本身代碼中操做mongo數據庫的接口,而robomongo是mongo數據庫的可視化工具,經過它的界面方便直接操做數據庫內容。數據庫
1.安裝mongoDBexpress
到官網https://www.mongodb.com/download-center#community下載程序安裝,選擇custom模式就行。npm
2.創建MongoDB環境
須要本身創建db目錄做爲數據庫環境,在命令行窗口中輸入
$ md \data\db
創建db文件夾後,在命令窗口中進入安裝目錄的bin文件夾執行mongod.exe,把數據庫安裝在datadb中。mongoDB會檢測你的根目錄是否有datadb文件夾,若是有會默認安裝到這個文件夾裏面。
$ cd C:\Program Files\MongoDB\Server\3.2\bin $ mongod.exe
固然也能夠直接在系統根目錄下建立datadb文件夾,而後在mongoDB安裝文件夾中雙擊執行mongod.exe。
3.啓動MongoDB
命令行工具中輸入:
$ cd C:\Program Files\MongoDB\Server\3.2\bin $ mongod.exe
爲了不每次都要輸入目錄,因此在系統變量裏面配置一下path變量,把";C:Program FilesMongoDBServer3.2bin"放到path後面(記得加;隔開),之後能夠直接在命令行窗口輸入mongod.exe回車便可。
在瀏覽器中輸入網址:http://localhost:27017/ 。若是服務啓動成功會看到如下一段話:It looks like you are trying to access MongoDB over HTTP on the native driver port.
4.鏈接MongoDB(這一步基本沒有用,只有在命令行工具中使用mongo原生方法時須要,而在mongoose裏面會有鏈接的代碼,Robomongo運行也會有鏈接)
命令行工具中輸入mongo.exe,回車。
若是出現這個警告:2016-07-16T14:49:02.827+0800 I CONTROL [main] Hotfix KB2731284 or later update is not installed, will zero-out data files那是由於Windows缺乏一個補丁,從這個連接下週補丁451413_intl_x64_zip,而後解壓安裝包,在你解壓的目錄下找到Windows6.1-KB2731284-v3-x64.mus安裝文件。安裝重啓便可。
直接到官網https://robomongo.org/下載安裝,安裝成功後運行,第一次運行,須要新建立一個鏈接,如圖建立test,點擊save保存鏈接。
選擇test,點擊connect鏈接數據庫。robomongo會本身搜索你係統裏面安裝的mongodb並與其鏈接。如圖
鏈接成功後,顯示你的數據庫,在這個節目能夠對數據庫進行操做。如圖:
首先假定你已經安裝了 Node.js,命令行工具輸入:
$ npm install mongoose -g
在使用的文件中require("mongoose");便可。
Mongose基於mongodb的原生方法,本身定義了一套操做MongoDB數據庫的接口,比原生方法更加簡單方便。爲了更加直觀,下面的步驟結合例子來說。假如我須要作一個教務系統,須要存儲學生Student的信息,學生信息一般包含姓名name,學號id,電話phone,登陸日期date等。我把學生的信息存在mongodb的myDB數據庫中,集合的名字叫students。如圖:
_id這個域你能夠本身定義,但若是你沒有定義,系統會自動給你加上。下面先介紹在node中經過mongoose對mongodb進行操做的必須前提步驟:
1.node鏈接數據庫
mongoose.connect('mongodb://user:pass@ip:port/database');
這只是最基本的鏈接,咱們通常還會加一些設置,是否開啓調試模式,鏈接提示等。一般我會這麼寫:
var mongoose = require("mongoose"); mongoose.Promise = global.Promise; /*調試模式是mongoose提供的一個很是實用的功能,用於查看mongoose模塊對mongodb操做的日誌,通常開發時會打開此功能,以便更好的瞭解和優化對mongodb的操做。*/ mongoose.set('debug', true); /*通常默認沒有user和password*/ var db=mongoose.connect('mongodb://localhost/myDB'); db.connection.on("error", function (error) { console.log("數據庫鏈接失敗:" + error); }); db.connection.on("open", function () { console.log("數據庫鏈接成功"); });
沒有mongoose.Promise = global.Promise會出現以下錯誤(這個錯誤沒有什麼影響):
意思是mongoose自帶的promise過時了,而後須要使用v8引擎的promise。
2.定義模式(Schema)
每一個模式映射mongoDB的一個集合(注意映射這個詞,下面會講爲何),它定義(只是定義,不是實現)這個集合裏面文檔的結構,就是定義這個文檔有什麼字段,字段類型是什麼,字段默認值是什麼等。除了定義結構外,還定義文檔的實例方法,靜態模型方法,複合索引,中間件等。詳情本身查看mongoose官方文檔。
var mongoose = require('mongoose'); var Schema = mongoose.Schema; /*定義模式Student_Schema*/ var Student_Schema = new Schema({ name: String, id: Number, phone: String, date: Date }, { versionKey: false }); /*定義模型Student,注意數據庫存的是students*/ mongoose.model("Student", Student_Schema);
{versionKey: false}是幹嗎用?若是不加這個設置,咱們經過mongoose第一次建立某個集合時,它會給這個集合設定一個versionKey屬性值,這個屬性值包含這個文檔的內部版本,數據庫中顯示爲_v,如圖:
經過{versionKey: false}能夠配置這個參數,讓數據庫再也不添加這個屬性,格式是:new Schema({..}, { versionKey: false });
3.定義模型(Model)
模型用來實現咱們定義的模式,調用mongoose.model來編譯Schema獲得Model。
/*定義模型Student,數據庫存的是students*/ mongoose.model("Student", Student_Schema);
爲何上面我強調模式的映射,那是由於模式僅僅是和db中集合文檔的結構相對應(映射),它並不直接在數據庫中操做這個結構,模型纔是直接與數據庫打交道的存在,能夠這麼說:模式是定義結構,模型是實現操做。當咱們使用mongoose.model("Student", Student_Schema)建立Student模型對數據進行操做時,數據庫會尋找一個名字叫students集合接受Student模型的操做,特別須要注意的是:1.若是是增長(instance.save)操做時,數據庫中沒有這個集合,數據庫會自動建立這個集合存儲數據,這個集合產生規則爲:把Model名字字母所有變小寫和在後面加複數s。2.若是是刪改查三個操做數據庫中沒有這個集合,那就是沒有,刪除空修改空返回空。
4.訪問模型
var MyStudent = mongoose.model("Student");
到這裏,已經基本完成了使用mongoose前提操做了。有沒有以爲有點繁瑣,其實我也以爲挺繁瑣,幸運的是234能夠一步建立:
var MyStudent = mongoose.model('Student',{ name: String, id: Number, phone: String, date: Date });
5.建立實例(instance)
var sam = new MyStudent({ name: "sam976", id: 123, phone: "18706888888", date: Date.now() });
通常只在save(增長)操做中須要。
模型的實例是集合中真實的數據,就是collection中的document,用mysql中的術語來講就是一條記錄。模型在數據庫中建好了集合和文檔結構後,經過實例往裏面添加真實的document。
捋一捋模式、模型、實例的關係:模式定義了操做和屬性,這些操做和屬性包括mongoose自帶和自定義,而模型和實例能夠對模式裏面定義的屬性和方法進行引用。模型是mongoose用來和數據庫直接打交道的中介,實例是往數據庫存的真實數據。模式並不是必須,那爲何要分開模式和模型呢?我以爲是遵循了軟件設計中「定義和實現分開」這個原則。有的文章說模式沒有操做數據庫的能力,模型纔有,對這個觀點,我以爲部分對,雖然說模式不能直接操做數據庫,但模式定義的方法能夠被模型用來操做數據庫。官方文檔是這麼說的:
Schemas not only define the structure of your document and casting of properties, they also define document instance methods, static Model methods, compound indexes and document lifecycle hooks called middleware.
以上是使用mongoose進行增刪查改操做都須要通過的前提步驟,下面正式介紹對數據庫的增刪查改(CRUD)操做。
1.CRUD之create
使用模型建立sam實例,sam實例調用save方法把document存入數據庫的students集合中,代碼以下
var MyStudent = mongoose.model("Student"); var sam = new MyStudent({ name: "sam976", id: 123, phone: "18706888888", date: Date.now() }); sam.save(function(err) {});
經過robomongo查看數據庫,能夠看到數據已經存放成功,如圖
2.CRUD之read
使用MyStudent模型調用find()方法返回students集合的全部內容,第一個參數定義條件,第二個參數是回調函數,回調函數中的docs是返回的是查找結果,結果形式爲一個json數據數組[{},{}]。
var MyStudent = mongoose.model("Student"); MyStudent.find({}, function(err, docs) {});
好比數據庫students集合中,有以下數據:
運行上面代碼,結果console.log輸出顯示以下:
模型還能夠調用其餘不少查詢的函數,好比
Model.findById(id, [projection], [options], [callback]); Model.findOne([conditions], [projection], [options], [callback]);
篇幅較多,這裏不攤開來說(之後會專門出一篇介紹),能夠本身查看官方文檔關於Querying介紹
3.CRUD之update
使用MyStudent模型調用update()方法完成更新,第一個參數是條件(也就是where name="sam976"),第二個參數修改的內容。
var MyStudent = mongoose.model("Student"); MyStudent.update({name:"sam976"},{id:456,phone:"12345678910"}, function(error){});
運行如上代碼前,如圖
運行如上代碼後,如圖
4.CRUD之delete
使用MyStudent模型調用remove()方法刪除文檔。
var MyStudent = mongoose.model("Student"); MyStudent.remove({ name: 'sam976' }, function (err) {});
使用mongoose的時候,一般會在項目中建立三個文件:connect.js,mongoose-db.js,app.js。
其中connect.js存放的是鏈接數據庫的操做,咱們只須要加載一次便可在程序運行期間一直鏈接數據庫。
mongoose-db.js文件存放模式和模型的生成的代碼,沒有鏈接信息,也沒有其餘額外不相干代碼,能夠在在mongoose-db.js中把模型exports公開:
var MyStudent = mongoose.model("Student", Student_Schema); exports.MyStudent=MyStudent; /*定義其餘模型和模式*/ var MyTeacher = mongoose.model("Teacher", Teacher_Schema); exports.MyTeacher=MyTeacher;
而後在app.js中引用:
var MyStudent = require("./mongoose-db").MyStudent; var MyTeacher = require("./mongoose-db").MyTeacher;
app.js存放對數據庫的操做,好比CRUD。經過這樣的方式,結構比較清晰,代碼可讀性大大加強。
下面放源碼(目的是給本身備份,笑臉...)
connect.js
var mongoose = require("mongoose"); mongoose.Promise = global.Promise;//爲了解決過時的問題 /*調試模式是mongoose提供的一個很是實用的功能,用於查看mongoose模塊對mongodb操做的日誌,通常開發時會打開此功能,以便更好的瞭解和優化對mongodb的操做。*/ mongoose.set('debug', true); /*mongoose會緩存命令,只要connect成功,處於其前其後的命令都會被執行,connect命令也就無所謂放哪裏*/ var db=mongoose.connect('mongodb://localhost/myDB'); db.connection.on("error", function (error) { console.log("數據庫鏈接失敗:" + error); }); db.connection.on("open", function () { console.log("數據庫鏈接成功");
mongoose-db.js
require('./connect'); var mongoose = require('mongoose'); var Schema = mongoose.Schema; /*定義模式Student_Schema*/ var Student_Schema = new Schema({ name: String, id: Number, phone: String, date: Date }, { versionKey: false }); /*定義模型Student,數據庫存的是students*/ var MyStudent = mongoose.model("Student", Student_Schema); exports.MyStudent=MyStudent; /*mongoose.Schema({ username: {// 真實姓名 type: String, required: true }, password: { // 密碼 type: String, required: true } });*/
app.js
require("./mongoose-db"); var express = require("express"); var mongoose = require("mongoose"); var MyStudent = require("./mongoose-db").MyStudent; var app = express(); app.use(express.static("./")); app.get("/create", function(req, res) { console.log("create 函數") var beta = new MyStudent({ name: "beta", id: 124, phone: "1871111111", date: Date.now() }); beta.save(function(err) { if (err) { console.log(err); } else { console.log('存入成功'); } }); res.send("存入成功!!"); }); app.get("/read", function(req, res) { console.log("讀取函數"); MyStudent.find({}, function(err, docs) { console.log(docs); /*對docs進行操做*/ }); res.send("讀取成功!!"); }); app.get("/readOne", function(req, res) { console.log("讀取單值函數"); MyStudent.findOne({ name: req.query.student_name }, { "id": 1, "_id": 0 }, function(err, docs) { if (docs.id === req.query.student_id) { res.send('登陸成功'); console.log(docs.password); } else { console.log(docs.password); res.send('登陸失敗'); } }); /*過濾查詢,參數2: {'name':1, 'password':0} 查詢文檔的返回結果包含name , 不包含password.(_id默認是1)*/ /*model.find({},null,{limit:20});過濾查詢,參數3: 遊標操做 limit限制返回結果數量爲20個,如不足20個則返回全部*/ }); app.get("/update", function(req, res) { console.log("更新函數"); MyStudent.update({ name: "sam976" }, { id: 456, phone: "12345678910" }, function(error) {}); res.send("更新成功!!"); }); app.get("/delete", function(req, res) { console.log("刪除函數"); MyStudent.remove({ name: 'sam976' }, function(err) { if (err) return handleError(err); // removed! }); res.send("刪除成功!!"); }); app.listen(3001, function() { console.log("start server") });
爲了測試,我還寫了個html。data-operate.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>data-operate</title> </head> <body> <form action="./create"> <input type="submit" value="建立"> </form> <br/> <form action="./read"> <input type="submit" value="讀取"> </form> <br/> <form action="./update"> <input type="submit" value="更新"> </form> <br/> <form action="./delete"> <input type="submit" value="刪除"> </form> <br/> <form action="./readOne"> <input type="text" name="student_name"> <input type="text" name="student_id"> <input type="submit" value="單值讀取"> </form> </body> </html>
上文是在Node中基於Mongoose對MongoDB進行增刪查改(CRUD)操做的簡單介紹,之後會有進階的文章。
參考文獻:
Node.js 手冊查詢-3-Mongoose 方法
Mongoose Schemas v4.5.8
mongoose入門