摘要:轉(zhuǎn)自一快速通道名詞解釋一種以文件形式存儲(chǔ)的數(shù)據(jù)庫模型骨架,不具備數(shù)據(jù)庫的操作能力由發(fā)布生成的模型,具有抽象屬性和行為的數(shù)據(jù)庫操作對(duì)由創(chuàng)建的實(shí)體,他的操作也會(huì)影響數(shù)據(jù)庫注意本學(xué)習(xí)文檔采用嚴(yán)格命名方式來區(qū)別不同對(duì)象,例如的文本屬性的數(shù)據(jù)庫模型實(shí)
轉(zhuǎn)自 https://cnodejs.org/topic/504...
一、快速通道 1.1 名詞解釋Schema : 一種以文件形式存儲(chǔ)的數(shù)據(jù)庫模型骨架,不具備數(shù)據(jù)庫的操作能力
Model : 由Schema發(fā)布生成的模型,具有抽象屬性和行為的數(shù)據(jù)庫操作對(duì)
Entity : 由Model創(chuàng)建的實(shí)體,他的操作也會(huì)影響數(shù)據(jù)庫
注意:
1.本學(xué)習(xí)文檔采用嚴(yán)格命名方式來區(qū)別不同對(duì)象,例如:
var PersonSchema; //Person的文本屬性 var PersonModel; //Person的數(shù)據(jù)庫模型 var PersonEntity; //Person實(shí)體
2.Schema、Model、Entity的關(guān)系請牢記,Schema生成Model,Model創(chuàng)造Entity,Model和Entity都可對(duì)數(shù)據(jù)庫操作造成影響,但Model比Entity更具操作性。
1.2 準(zhǔn)備工作1.首先你必須安裝MongoDB和NodeJS
2.在項(xiàng)目只能夠創(chuàng)建一個(gè)數(shù)據(jù)庫連接,如下:
var mongoose = require("mongoose"); //引用mongoose模塊 var db = mongoose.createConnection("localhost","test"); //創(chuàng)建一個(gè)數(shù)據(jù)庫連接
3.打開本機(jī)localhost的test數(shù)據(jù)庫時(shí),我們可以監(jiān)測是否有異常
db.on("error",console.error.bind(console,"連接錯(cuò)誤:")); db.once("open",function(){ //一次打開記錄 });
注意:
成功開啟數(shù)據(jù)庫后,就可以執(zhí)行數(shù)據(jù)庫相應(yīng)操作,假設(shè)以下代碼都在回調(diào)中處理
4.定義一個(gè)Schema
var PersonSchema = new mongoose.Schema({ name:String //定義一個(gè)屬性name,類型為String });
5.將該Schema發(fā)布為Model
var PersonModel = db.model("Person",PersonSchema); //如果該Model已經(jīng)發(fā)布,則可以直接通過名字索引到,如下: //var PersonModel = db.model("Person"); //如果沒有發(fā)布,上一段代碼將會(huì)異常
6.用Model創(chuàng)建Entity
var personEntity = new PersonModel({name:"Krouky"}); //打印這個(gè)實(shí)體的名字看看 console.log(personEntity.name); //Krouky
7.我們甚至可以為此Schema創(chuàng)建方法
//為Schema模型追加speak方法 PersonSchema.methos.speak = function(){ console.log("我的名字叫"+this.name); } var PersonModel = db.model("Person",PersonSchema); var personEntity = new PersonModel({name:"Krouky"}); personEntity.speak();//我的名字叫Krouky
8.Entity是具有具體的數(shù)據(jù)庫操作CRUD的
personEntity.save(); //執(zhí)行完成后,數(shù)據(jù)庫就有該數(shù)據(jù)了
9.如果要執(zhí)行查詢,需要依賴Model,當(dāng)然Entity也是可以做到的
PersonModel.find(function(err,persons){ //查詢到的所有person });
注意:
具體的如何配置Schema、Model以及Model和Entity的相關(guān)操作,我們會(huì)在后面進(jìn)行
Model和Entity都有能影響數(shù)據(jù)庫的操作,但仍有區(qū)別,后面我們也會(huì)做解釋
二、新手指引如果您還不清楚Mongoose是如何工作的,請參看第一章快速通道快速瀏覽他的用法吧
1. Schema——純潔的數(shù)據(jù)庫原型 1.1 什么是Schema我理解Schema僅僅只是一斷代碼,他書寫完成后程序依然無法使用,更無法通往數(shù)據(jù)庫端
他僅僅只是數(shù)據(jù)庫模型在程序片段中的一種表現(xiàn),或者是數(shù)據(jù)屬性模型
var BlogSchema = new Schema({ title:String, author:String //new Schema()中傳入一個(gè)JSON對(duì)象,該對(duì)象形如 xxx:yyyy , /xxx是一個(gè)字符串,定義了屬性,yyy是一個(gè)Schema.Type,定義了屬性類型 });1.3 什么是Schema.Type
Schema.Type是由Mongoose內(nèi)定的一些數(shù)據(jù)類型,基本數(shù)據(jù)類型都在其中,他也內(nèi)置了一些Mongoose特有的Schema.Type。當(dāng)然,你也可以自定義Schema.Type,只有滿足Schema.Type的類型才能定義在Schema內(nèi)。
1.4 Schema.TypesNodeJS中的基本數(shù)據(jù)類型都屬于Schema.Type,另外Mongoose還定義了自己的類型
//舉例: var ExampleSchema = new Schema({ name:String, binary:Buffer, living:Boolean, updated:Date, age:Number, mixed:Schema.Types.Mixed, //該混合類型等同于nested _id:Schema.Types.ObjectId, //主鍵 _fk:Schema.Types.ObjectId, //外鍵 array:[], arrOfString:[String], arrOfNumber:[Number], arrOfDate:[Date], arrOfBuffer:[Buffer], arrOfBoolean:[Boolean], arrOfMixed:[Schema.Types.Mixed], arrOfObjectId:[Schema.Types.ObjectId] nested:{ stuff:String, } });1.5 關(guān)于Buffer
Buffer和ArrayBuffer是Nodejs兩種隱藏的對(duì)象,相關(guān)內(nèi)容請查看NodeJS-API
1.6 關(guān)于MixedSchema.Types.Mixed是Mongoose定義個(gè)混合類型,該混合類型如果未定義具體形式。因此,如果定義具體內(nèi)容,就直接使用{}來定義,以下兩句等價(jià)
var AnySchema = new Schema({any:{}}); var AnySchema = new Schema({any:Schema.Types.Mixed});
混合類型因?yàn)闆]有特定約束,因此可以任意修改,一旦修改了原型,則必須調(diào)用markModified()
person.anything = {x:[3,4,{y:"change"}]} person.markModified("anything");//傳入anything,表示該屬性類型發(fā)生變化 person.save();1.7 關(guān)于ObjectId
主鍵,一種特殊而且非常重要的類型,每個(gè)Schema都會(huì)默認(rèn)配置這個(gè)屬性,屬性名為_id,除非自己定義,方可覆蓋
var mongoose = require("mongoose"); var ObjectId = mongoose.Schema.Types.ObjectId; var StudentSchema = new Schema({}); //默認(rèn)會(huì)有_id:ObjectId var TeacherSchema = new Schema({id:ObjectId});//只有id:ObjectId
該類型的值由系統(tǒng)自己生成,從某種意義上幾乎不會(huì)重復(fù),生成過程比較復(fù)雜,有興趣的朋友可以查看源碼。
1.8 關(guān)于ArrayArray在JavaScript編程語言中并不是數(shù)組,而是集合,因此里面可以存入不同的值,以下代碼等價(jià):
var ExampleSchema1 = new Schema({array:[]}); var ExampleSchema2 = new Schema({array:Array}); var ExampleSchema3 = new Schema({array:[Schema.Types.Mixed]}); var ExampleSchema4 = new Schema({array:[{}]});1.9 附言
Schema不僅定義了文檔結(jié)構(gòu)和使用性能,還可以有擴(kuò)展插件、實(shí)例方法、靜態(tài)方法、復(fù)合索引、文檔生命周期鉤子
Schema可以定義插件,并且插件具有良好的可拔插性,請有興趣的讀者繼續(xù)往后閱讀或者查閱官方資料。
2. Schema的擴(kuò)展 2.1 實(shí)例方法有的時(shí)候,我們創(chuàng)造的Schema不僅要為后面的Model和Entity提供公共的屬性,還要提供公共的方法。
下面例子比快速通道的例子更加高級(jí),可以進(jìn)行高級(jí)擴(kuò)展:
var PersonSchema = new Schema({name:String,type:String}); //查詢類似數(shù)據(jù) PersonSchema.methods.findSimilarTypes = function(cb){ return this.model("Person").find({type:this.type},cb); }
使用如下:
var PersonModel = mongoose.model("Person",PersonSchema); var krouky = new PersonSchema({name:"krouky",type:"前端工程師"}); krouky.findSimilarTypes(function(err,persons){ //persons中就能查詢到其他前端工程師 });2.2 靜態(tài)方法
靜態(tài)方法在Model層就能使用,如下:
PersonSchema.statics.findByName = function(name,cb){
this.find({name:new RegExp(name,"i"),cb});
}
var PersonModel = mongoose.model("Person",PersonSchema);
PersonModel.findByName("krouky",function(err,persons){
//找到所有名字叫krouky的人
});
2.3 索引索引或者復(fù)合索引能讓搜索更加高效,默認(rèn)索引就是主鍵索引ObjectId,屬性名為_id, 索引會(huì)作為一個(gè)專題來講解
2.4 虛擬屬性Schema中如果定義了虛擬屬性,那么該屬性將不寫入數(shù)據(jù)庫,例如:
var PersonSchema = new Schema({ name:{ first:String, last:String } }); var PersonModel = mongoose.model("Person",PersonSchema); var krouky = new PersonModel({ name:{first:"krouky",last:"han"} });
如果每次想使用全名就得這樣
console.log(krouky.name.first + " " + krouky.name.last);
顯然這是很麻煩的,我們可以定義虛擬屬性:
PersonSchema.virtual("name.full").get(function(){ return this.name.first + " " + this.name.last; });
那么就能用krouky.name.full來調(diào)用全名了,反之如果知道full,也可以反解first和last屬性
PersonSchema.virtual("name.full").set(function(name){ var split = name.split(" "); this.name.first = split[0]; this.name.last = split[1]; }); var PersonModel = mongoose.model("Person",PersonSchema); var krouky = new PersonModel({}); krouky.name.full = "krouky han";//會(huì)被自動(dòng)分解 console.log(krouky.name.first);//krouky2.5 配置項(xiàng)
在使用new Schema(config)時(shí),我們可以追加一個(gè)參數(shù)options來配置Schema的配置,形如:
var ExampleSchema = new Schema(config,options);
或者使用
var ExampleSchema = new Schema(config); ExampleSchema.set(option,value);
可供配置項(xiàng)有:safe、strict、capped、versionKey、autoIndex
一般可做如下配置:
new Schema({...},{safe:true});
當(dāng)然我們也可以這樣
new Schema({...},{safe:{j:1,w:2,wtimeout:10000}});
j表示做1份日志,w表示做2個(gè)副本(尚不明確),超時(shí)時(shí)間10秒
確保Entity的值存入數(shù)據(jù)庫前會(huì)被自動(dòng)驗(yàn)證,如果你沒有充足的理由,請不要停用,例子:
var ThingSchema = new Schema({a:String}); var ThingModel = db.model("Thing",SchemaSchema); var thing = new Thing({iAmNotInTheThingSchema:true}); thing.save();//iAmNotInTheThingSchema這個(gè)屬性將無法被存儲(chǔ)
如果取消嚴(yán)格選項(xiàng),iAmNotInTheThingSchema將會(huì)被存入數(shù)據(jù)庫
該選項(xiàng)也可以在構(gòu)造實(shí)例時(shí)使用,例如:
var ThingModel = db.model("Thing"); var thing1 = new ThingModel(doc,true); //啟用嚴(yán)格 var thing2 = new ThingModel(doc,false); //禁用嚴(yán)格
注意:
strict也可以設(shè)置為throw,表示出現(xiàn)問題將會(huì)拋出錯(cuò)誤
需要mongodb做分布式,才會(huì)使用該屬性
如果有數(shù)據(jù)庫的批量操作,該屬性能限制一次操作的量,例如:
new Schema({...},{capped:1024}); //一次操作上線1024條數(shù)據(jù)
當(dāng)然該參數(shù)也可是JSON對(duì)象,包含size、max、autiIndexId屬性
new Schema({...},{capped:{size:1024,max:100,autoIndexId:true}});
版本鎖是Mongoose默認(rèn)配置(__v屬性)的,如果你想自己定制,如下:
new Schema({...},{versionKey:"__someElse"});
此時(shí)存入數(shù)據(jù)庫的版本鎖就不是__v屬性,而是__someElse,相當(dāng)于是給版本鎖取名字。
具體怎么存入都是由Mongoose和MongoDB自己決定,當(dāng)然,這個(gè)屬性你也可以去除
new Schema({...},{versionKey:false});
除非你知道你在做什么,并且你知道這樣做的后果
該內(nèi)容將在索引章節(jié)多帶帶講解
3. DocumentsDocument是與MongoDB文檔一一對(duì)應(yīng)的模型,Document可等同于Entity,具有屬性和操作性
注意:
Document的`CRUD都必須經(jīng)過嚴(yán)格驗(yàn)證的,參看2.5.2 Schema的strict嚴(yán)格配置
3.1 查詢查詢內(nèi)容過多,專題講解
3.2 更新有許多方式來更新文件,以下是常用的傳統(tǒng)方式:
PersonModel.findById(id,function(err,person){ person.name = "MDragon"; person.save(function(err){}); });
這里,利用Model模型查詢到了person對(duì)象,該對(duì)象屬于Entity,可以有save操作,如果使用Model`操作,需注意:
PersonModel.findById(id,function(err,person){ person.name = "MDragon"; var _id = person._id; //需要取出主鍵_id delete person._id; //再將其刪除 PersonModel.update({_id:_id},person,function(err){}); //此時(shí)才能用Model操作,否則報(bào)錯(cuò) });
update第一個(gè)參數(shù)是查詢條件,第二個(gè)參數(shù)是更新的對(duì)象,但不能更新主鍵,這就是為什么要?jiǎng)h除主鍵的原因。
當(dāng)然這樣的更新很麻煩,可以使用$set屬性來配置,這樣也不用先查詢,如果更新的數(shù)據(jù)比較少,可用性還是很好的:
PersonModel.update({_id:_id},{$set:{name:"MDragon"}},function(err){});
需要注意,Document的CRUD操作都是異步執(zhí)行,callback第一個(gè)參數(shù)必須是err,而第二個(gè)參數(shù)各個(gè)方法不一樣,update的callback第二個(gè)參數(shù)是更新的數(shù)量,如果要返回更新后的對(duì)象,則要使用如下方法
Person.findByIdAndUpdate(_id,{$set:{name:"MDragon"}},function(err,person){ console.log(person.name); //MDragon });
類似的方法還有findByIdAndRemove,如同名字,只能根據(jù)id查詢并作update/remove操作,操作的數(shù)據(jù)僅一條
3.3 新增如果是Entity,使用save方法,如果是Model,使用create方法
//使用Entity來增加一條數(shù)據(jù) var krouky = new PersonModel({name:"krouky"}); krouky.save(callback); //使用Model來增加一條數(shù)據(jù) var MDragon = {name:"MDragon"}; PersonModel.create(MDragon,callback);
兩種新增方法區(qū)別在于,如果使用Model新增時(shí),傳入的對(duì)象只能是純凈的JSON對(duì)象,不能是由Model創(chuàng)建的實(shí)體,原因是:由Model創(chuàng)建的實(shí)體krouky雖然打印是只有{name:"krouky"},但是krouky屬于Entity,包含有Schema屬性和Model數(shù)據(jù)庫行為模型。如果是使用Model創(chuàng)建的對(duì)象,傳入時(shí)一定會(huì)將隱藏屬性也存入數(shù)據(jù)庫,雖然3.x追加了默認(rèn)嚴(yán)格屬性,但也不必要增加操作的報(bào)錯(cuò)
3.4 刪除和新增一樣,刪除也有2種方式,但Entity和Model都使用remove方法
4.Sub Docs如同SQL數(shù)據(jù)庫中2張表有主外關(guān)系,Mongoose將2個(gè)Document的嵌套叫做Sub-Docs(子文檔)
簡單的說就是一個(gè)Document嵌套另外一個(gè)Document或者Documents:
var ChildSchema1 = new Schema({name:String}); var ChildSchema2 = new Schema({name:String}); var ParentSchema = new Schema({ children1:ChildSchema1, //嵌套Document children2:[ChildSchema2] //嵌套Documents });
Sub-Docs享受和Documents一樣的操作,但是Sub-Docs的操作都由父類去執(zhí)行
var ParentModel = db.model("Parent",parentSchema); var parent = new ParentModel({ children2:[{name:"c1"},{name:"c2"}] }); parent.children2[0].name = "d"; parent.save(callback);
parent在執(zhí)行保存時(shí),由于包含children2,他是一個(gè)數(shù)據(jù)庫模型對(duì)象,因此會(huì)先保存chilren2[0]和chilren2[1]。
如果子文檔在更新時(shí)出現(xiàn)錯(cuò)誤,將直接報(bào)在父類文檔中,可以這樣處理:
ChildrenSchema.pre("save",function(next){ if("x" === this.name) return next(new Error("#err:not-x")); next(); }); var parent = new ParentModel({children1:{name:"not-x"}}); parent.save(function(err){ console.log(err.message); //#err:not-x });4.1 查詢子文檔
如果children是parent的子文檔,可以通過如下方法查詢到children
var child = parent.children.id(id);4.2 新增、刪除、更新
子文檔是父文檔的一個(gè)屬性,因此按照屬性的操作即可,不同的是在新增父類的時(shí)候,子文檔是會(huì)被先加入進(jìn)去的。
如果ChildrenSchema是臨時(shí)的一個(gè)子文檔,不作為數(shù)據(jù)庫映射集合,可以這樣:
var ParentSchema = new Schema({ children:{ name:String } }); //其實(shí)就是匿名混合模式5.Model 5.1 什么是Model
Model模型,是經(jīng)過Schema構(gòu)造來的,除了Schema定義的數(shù)據(jù)庫骨架以外,還具有數(shù)據(jù)庫行為模型,他相當(dāng)于管理數(shù)據(jù)庫屬性、行為的類
5.2 如何創(chuàng)建Model你必須通過Schema來創(chuàng)建,如下:
//先創(chuàng)建Schema var TankSchema = new Schema({ name:"String", size:"String" }); //通過Schema創(chuàng)建Model var TankModel = mongoose.model("Tank",TankSchema);5.2 操作Model
該模型就能直接拿來操作,具體查看API,例如:
var tank = {"something",size:"small"}; TankModel.create(tank);
注意:
你可以使用Model來創(chuàng)建Entity,Entity實(shí)體是一個(gè)特有Model具體對(duì)象,但是他并不具備Model的方法,只能用自己的方法。
//通過Model創(chuàng)建Entity
var tankEntity = new TankModel("someother","size:big");
tankEntity.save();
查詢是數(shù)據(jù)庫中運(yùn)用最多也是最麻煩的地方,這里對(duì)Query解讀的并不完善,僅僅是自己的一點(diǎn)領(lǐng)悟而已。
6.1 查詢的方式通常有2種查詢方式,一種是直接查詢,一種是鏈?zhǔn)讲樵儯?種查詢都是自己命名的)
在查詢時(shí)帶有回調(diào)函數(shù)的,稱之為直接查詢,查詢的條件往往通過API來設(shè)定,例如:
PersonModel.findOne({"name.last":"dragon"},"some select",function(err,person){ //如果err==null,則person就能取到數(shù)據(jù) });
具體的查詢參數(shù),請查詢API
在查詢時(shí)候,不帶回調(diào),而查詢條件通過API函數(shù)來制定,例如:
var query = PersonModel.findOne({"name.last":"dragon"}); query.select("some select"); query.exec(function(err,pserson){ //如果err==null,則person就能取到數(shù)據(jù)
});
這種方式相對(duì)直接查詢,分的比較明細(xì),如果不帶callback,則返回query,query沒有執(zhí)行的預(yù)編譯查詢語句,該query對(duì)象執(zhí)行的方法都將返回自己,只有在執(zhí)行exec方法時(shí)才執(zhí)行查詢,而且必須有回調(diào)。
因?yàn)閝uery的操作始終返回自身,我們可以采用更形象的鏈?zhǔn)綄懛?/p>
Person .find({ occupation: /host/ }) .where("name.last").equals("Ghost") .where("age").gt(17).lt(66) .where("likes").in(["vaporizing", "talking"]) .limit(10) .sort("-occupation") .select("name occupation") .exec(callback);7.Validation
數(shù)據(jù)的存儲(chǔ)是需要驗(yàn)證的,不是什么數(shù)據(jù)都能往數(shù)據(jù)庫里丟或者顯示到客戶端的,數(shù)據(jù)的驗(yàn)證需要記住以下規(guī)則:
驗(yàn)證始終定義在SchemaType中
驗(yàn)證是一個(gè)內(nèi)部中間件
驗(yàn)證是在一個(gè)Document被保存時(shí)默認(rèn)啟用的,除非你關(guān)閉驗(yàn)證
驗(yàn)證是異步遞歸的,如果你的SubDoc驗(yàn)證失敗,Document也將無法保存
驗(yàn)證并不關(guān)心錯(cuò)誤類型,而通過ValidationError這個(gè)對(duì)象可以訪問
required 非空驗(yàn)證
min/max 范圍驗(yàn)證(邊值驗(yàn)證)
enum/match 枚舉驗(yàn)證/匹配驗(yàn)證
validate 自定義驗(yàn)證規(guī)則
以下是綜合案例:
var PersonSchema = new Schema({ name:{ type:"String", required:true //姓名非空 }, age:{ type:"Nunmer", min:18, //年齡最小18 max:120 //年齡最大120 }, city:{ type:"String", enum:["北京","上海"] //只能是北京、上海人 }, other:{ type:"String", validate:[validator,err] //validator是一個(gè)驗(yàn)證函數(shù),err是驗(yàn)證失敗的錯(cuò)誤信息 } });7.2 驗(yàn)證失敗
如果驗(yàn)證失敗,則會(huì)返回err信息,err是一個(gè)對(duì)象該對(duì)象屬性如下
err.errors //錯(cuò)誤集合(對(duì)象) err.errors.color //錯(cuò)誤屬性(Schema的color屬性) err.errors.color.message //錯(cuò)誤屬性信息 err.errors.path //錯(cuò)誤屬性路徑 err.errors.type //錯(cuò)誤類型 err.name //錯(cuò)誤名稱 err.message //錯(cuò)誤消息
一旦驗(yàn)證失敗,Model和Entity都將具有和err一樣的errors屬性
8.Middleware中間件 8.1 什么是中間件中間件是一種控制函數(shù),類似插件,能控制流程中的init、validate、save、remove`方法
8.2 中間件的分類中間件分為兩類
串行使用pre方法,執(zhí)行下一個(gè)方法使用next調(diào)用
var schema = new Schema(...); schema.pre("save",function(next){ //做點(diǎn)什么 next(); });
并行提供更細(xì)粒度的操作
var schema = new Schema(...); schema.pre("save",function(next,done){ //下一個(gè)要執(zhí)行的中間件并行執(zhí)行 next(); doAsync(done); });8.3 中間件特點(diǎn)
一旦定義了中間件,就會(huì)在全部中間件執(zhí)行完后執(zhí)行其他操作,使用中間件可以霧化模型,避免異步操作的層層迭代嵌套
8.4 使用范疇復(fù)雜的驗(yàn)證
刪除有主外關(guān)聯(lián)的doc
異步默認(rèn)
某個(gè)特定動(dòng)作觸發(fā)異步任務(wù),例如觸發(fā)自定義事件和通知
例如,可以用來做自定義錯(cuò)誤處理
schema.pre("save",function(next){ var err = new Eerror("some err"); next(err); }); entity.save(function(err){ console.log(err.message); //some err });
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/18964.html
摘要:根據(jù)個(gè)人編碼習(xí)慣,僅供參考如中途看的有點(diǎn)蒙圈,可以轉(zhuǎn)到官網(wǎng)查看引入模塊連接數(shù)據(jù)庫鏈接狀態(tài)數(shù)據(jù)庫鏈接成功為了查看是否鏈接成功所以做一個(gè)回調(diào)創(chuàng)建模式對(duì)象例將賦值給變量創(chuàng)建對(duì)象官網(wǎng)創(chuàng)建通過來創(chuàng)建代表的是數(shù)據(jù)庫中的集合,通過才能對(duì)數(shù)據(jù)庫進(jìn)行操作可在 根據(jù)個(gè)人編碼習(xí)慣,僅供參考 如中途看的有點(diǎn)蒙圈,可以轉(zhuǎn)到官網(wǎng)查看 引入模塊 var mongoose = require(mongoose); ...
摘要:的邏輯結(jié)構(gòu)是一種層次結(jié)構(gòu),主要由文檔集合數(shù)據(jù)庫這三部分組成的。文檔由鍵值對(duì)構(gòu)成,像等,它是核心單元,的文檔,相當(dāng)于關(guān)系數(shù)據(jù)庫中的一行記錄。我們以此為例看它如何使用真實(shí)項(xiàng)目中參考學(xué)習(xí)筆記之的使用入門教程的一些操作命令 showImg(https://segmentfault.com/img/bVN45N?w=1192&h=578); 簡介 在說MongoDB數(shù)據(jù)插入操作之前,我們先來簡單...
摘要:使用可以實(shí)現(xiàn)在一個(gè)中填充其他的。表示關(guān)聯(lián)注意被關(guān)聯(lián)的的必須是和才有效。封裝了很多查詢的方法,使得對(duì)數(shù)據(jù)庫的操作變得簡單啦。這里分享一下方法用法。類型的時(shí),格式如為表示不填充,為時(shí)表示填充。類型,可選,指定附加的查詢條件。 Mongoose 是 MongoDB 的 ODM(Object Document Mapper)。 什么是ODM? 其實(shí)和ORM(Object Relational...
稍微整理了一下自己平時(shí)看到的前端學(xué)習(xí)資源,分享給大家。 html MDN:Mozilla開發(fā)者網(wǎng)絡(luò) SEO:前端開發(fā)中的SEO css 張鑫旭:張鑫旭的博客 css精靈圖:css精靈圖實(shí)踐 柵格系統(tǒng):詳解CSS中的柵格系統(tǒng) 媒體查詢:css媒體查詢用法 rem布局:手機(jī)端頁面自適應(yīng)布局 移動(dòng)前端開發(fā)之viewport的深入理解:深入理解viewport 淘寶前端布局:手機(jī)淘寶移動(dòng)端布局 fl...
閱讀 4100·2023-04-26 01:48
閱讀 3270·2021-10-13 09:40
閱讀 1748·2021-09-26 09:55
閱讀 3636·2021-08-12 13:23
閱讀 1796·2021-07-25 21:37
閱讀 3437·2019-08-30 15:53
閱讀 1399·2019-08-29 14:16
閱讀 1403·2019-08-29 12:59