国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

mongoose學(xué)習(xí)筆記(超詳細(xì))

Bowman_han / 2566人閱讀

摘要:返回的是轉(zhuǎn)換為字符串后的值。默認(rèn)行為禁止在一個(gè)中如果沒有定義域,那么將會默認(rèn)分配一個(gè)域。通過在中設(shè)置這個(gè)字段可以阻止生成獲得。我們也能設(shè)置其它的安全等級如表示如果秒內(nèi)寫操作沒有完成,將會超時(shí)。在,和方法只檢查頂級的的選項(xiàng)設(shè)置。

原文出處

名詞解釋

Schema: 一種以文件形式存儲的數(shù)據(jù)庫模型骨架,不具備數(shù)據(jù)庫的操作能力

Model: 由Schema編譯而成的假想(fancy)構(gòu)造器,具有抽象屬性和行為。Model的每一個(gè)實(shí)例(instance)就是一個(gè)document。document可以保存到數(shù)據(jù)庫和從數(shù)據(jù)庫返回。

Instance: 由Model創(chuàng)建的實(shí)例。

概念解析
SQL術(shù)語/概念 MongoDB術(shù)語/概念 解釋/說明
rdatabase database -
table collection 數(shù)據(jù)庫表/集合
row document 數(shù)據(jù)記錄行/文檔
column index 數(shù)據(jù)記錄行/文檔
table joins - 表連接,MongoDB不支持
primary key primary key 主鍵 MongoDB自動將_id字段設(shè)置為主鍵
定義Schema

mongoose中任何任何事物都是從Schema開始的。每一個(gè)Schema對應(yīng)MongoDB中的一個(gè)集合(collection)。Schema中定義了集合中文檔(document)的樣式。

var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var blogSchema = new Schema({  
    title:  String,  
    author: String,  
    body:   String,  
    comments: [{ body: String, date: Date }],  
    date: { type: Date, default: Date.now },  
    hidden: Boolean, 
    meta: {    votes: Number,    favs:  Number  }
});

如果之后想要在Schema中添加鍵,可以使用Schema#add方法。

創(chuàng)造一個(gè)model

為了使用schema定義,我們需要轉(zhuǎn)換blogSchema為一個(gè)Model。使用

mongoose.model(modelName, schema)
var BlogModel = mongoose.model("Blog", blogSchema);// 開始吧!
實(shí)例方法

Model的實(shí)例是document。實(shí)例有很多內(nèi)置的方法,我們也可以給實(shí)例自定義方法。

var animalSchema = new Schema({ 
    name: String, type: String    
});
animalSchema.methods.findSimilarTypes = function (cb) {
    return this.model("Animal").find({ type: this.type }, cb);
}

現(xiàn)在所有的動物實(shí)例有findSimilarTypes方法。

var AnimalModel = mongoose.model("Animal", animalSechema);
var dog = new AnimalModel({ type: "dog" });
dog.findSimilarTypes(function (err, dogs) { 
    console.log(dogs); // woof
});

重寫一個(gè)默認(rèn)的實(shí)例方法可能會導(dǎo)致不期待的結(jié)果。

Statics方法

給Model添加一個(gè)靜態(tài)方法也是簡單的。

animalSchema.statics.findByName = function (name, cb) {
    this.find({ name: new RegExp(name, "i") }, cb);
}

var AnimalModel = mongoose.model("Animal", animalSchema);
AnimalModel.findByName("fido", function (err, animals) { 
    console.log(animals);
});
methods和statics的區(qū)別

區(qū)別就是一個(gè)給Model添加方法(statics),
一個(gè)給實(shí)例添加方法(methods)。

索引

MongoDB支持二級索引,定義索引有兩種方式

路徑級別 schema級別

var animalSchema = new Schema({  
    name: String,  
    type: String,  
    tags: { type: [String], index: true } // field level
    });

animalSchema.index({ name: 1, type: -1 }); // schema level, 1是正序,-1是倒序

如果要建立復(fù)合索引的話,在schema級別建立是必要的。

索引或者復(fù)合索引能讓搜索更加高效,默認(rèn)索引就是主鍵索引ObjectId,屬性名為_id。

數(shù)據(jù)庫中主要的就是CRUD操作,建立索引可以提高查詢速度。但是過多的索引會降低CUD操作。深度好文如下

http://www.cnblogs.com/huangx...

虛擬屬性

Schema中如果定義了虛擬屬性,那么該屬性將不寫入數(shù)據(jù)庫。寫入數(shù)據(jù)庫的還是原來的屬性。

// 定義一個(gè)schema

var personSchema = new Schema({  
    name: {  first: String,    last: String  }
});

// 編譯
var Person = mongoose.model("Person", personSchema);// 創(chuàng)造實(shí)例

var bad = new Person({ 
    name: { first: "Walter", last: "White" }
});

我們將名字分成名字和姓,如果要得到全名,我們需要

console.log(bad.name.first + " " + bad.name.last); // Walter White

這樣無疑是麻煩的,我們可以通過虛擬屬性的getter來解決這個(gè)問題。

personSchema.virtual("name.full").get(function () { 
    return this.name.first + " " + this.name.last;
});

那么就可以使用bad.name.full直接調(diào)用全名了。

反之,如果我們知道虛擬屬性name.full,通過setter也可以得到組成name.full的每一項(xiàng)。

personSchema.virtual("name.full").set(function (name) {  
    var split = name.split(" ");  
    this.name.first = split[0];  
    this.name.last = split[1];
});
...
mad.name.full = "Breaking Bad";
console.log(mad.name.first); // Breaking
console.log(mad.name.last);  // Bad
配置項(xiàng)

schema有一些配置項(xiàng)可以使用,有兩種方式:

new Schema({…}, options)

var schema = new Schema({...});
schema.set(option, value);

有效的配置有:

autoIndex(默認(rèn)true)

capped

collection

id _id(默認(rèn)true)

read safe(默認(rèn)true)

shardKey strict(默認(rèn)true)

toJSON

toObject

versionKey

typeKey

validateBeforeSave

skipVersioning

timestamps

useNestedStrict

retainKeyOrder

autoIndex–自動索引

應(yīng)用開始的時(shí)候,Mongoose對每一個(gè)索引發(fā)送一個(gè)ensureIndex的命令。索引默認(rèn)(_id)被Mongoose創(chuàng)建。

當(dāng)我們不需要設(shè)置索引的時(shí)候,就可以通過設(shè)置這個(gè)選項(xiàng)。

var schema = new Schema({..}, { autoIndex: false });
var Clock = mongoose.model("Clock", schema);
Clock.ensureIndexes(callback);
bufferCommands

似乎是說這個(gè)(mongoose buffer)管理在mongoose連接關(guān)閉的時(shí)候重連,如果取消buffer設(shè)置,如下:(存疑)

var schema = new Schema({..}, { bufferCommands: false });
capped–上限設(shè)置

如果有數(shù)據(jù)庫的批量操作,該屬性能限制一次操作的量,例如:

new Schema({...},{capped:1024});  //一次操作上線1024條數(shù)據(jù)

當(dāng)然該參數(shù)也可是對象,包含size、max、autiIndexId屬性

new Schema({...},{capped:{size:1024,max:100,autoIndexId:true}});
collection–集合名字

在MongDB中默認(rèn)使用Model的名字作為集合的名字,如過需要自定義集合的名字,可以通過設(shè)置這個(gè)選項(xiàng)。

var schema = new Schema({...}, {collection: "yourName"});
id

mongoose分配給每一個(gè)schema一個(gè)虛擬屬性id,它是一個(gè)getter。返回的是_id轉(zhuǎn)換為字符串后的值。如果不需要為schema添加這個(gè)getter,可以通過id配置修改。

// 默認(rèn)行為
var pageSchema = new Schema({ name: String });
var pageModel = mongoose.model("Page", pageSchema);
var p = new pageModel({ name: "mongodb.org" });
console.log(p.id); // "50341373e894ad16347efe01"

// 禁止id
var pageSchema = new Schema({ name: String }, { id: false } );
var pageModel = mongoose.model("Page", pageSchema);
var p = new pageModel({ name: "mongodb.org" });
console.log(p.id); // undefined
_id

在一個(gè)schema中如果沒有定義_id域(field),那么mongoose將會默認(rèn)分配一個(gè)_id域(field)。類型是ObjectId。如果不需要使用這個(gè)默認(rèn)的選擇,可以通過設(shè)置這個(gè)選項(xiàng)。

通過在schema中設(shè)置這個(gè)字段可以阻止生成mongoose獲得_id。但是在插入的時(shí)候仍然會生成_id。設(shè)置這個(gè)字段之后,如果再使用Schema.set(’_id’, false)將無效。

// 默認(rèn)行為
var pageSchema = new Schema({ name: String });
var pageModel = mongoose.model("Page", pageSchema);
var p = new pageModel({ name: "mongodb.org" });
console.log(p); // { _id: "50341373e894ad16347efe01", name: "mongodb.org" }

// 禁用 _id
var pageSchema = new Schema({ name: String }, { _id: false });
// schema構(gòu)造器設(shè)置之后,不要再像下面這樣設(shè)置
// var schema = new Schema({ name: String });
// schema.set("_id", false);

var PageModel = mongoose.model("Page", pageSchema);
var p = new pageModel({ name: "mongodb.org" });
console.log(p); // { name: "mongodb.org" }
// 當(dāng)插入的時(shí)候,MongoDB將會創(chuàng)建_id
p.save(function (err) {  
    if (err) return handleError(err);  
    pageModel.findById(p, function (err, doc) { 
        if (err) return handleError(err);   
        console.log(doc); 
        // { name: "mongodb.org", _id: "50341373e894ad16347efe12" }  
    })
})

為什么不建議使用set

read

允許在schema級別設(shè)置query#read,對于所有的查詢,提供給我們一種方法應(yīng)用默認(rèn)的ReadPreferences。

safe

這個(gè)配置會在MongoDB所有的操作中起作用。如果設(shè)置成true就是在操作的時(shí)候要等待返回的MongoDB返回的結(jié)果,比如update,要返回影響的條數(shù),才往后執(zhí)行,如果safe:false,則表示不用等到結(jié)果就向后執(zhí)行了。
默認(rèn)設(shè)置為true能保證所有的錯誤能通過我們寫的回調(diào)函數(shù)。我們也能設(shè)置其它的安全等級如:

{ j: 1, w: 2, wtimeout: 10000 }

表示如果10秒內(nèi)寫操作沒有完成,將會超時(shí)。
關(guān)于j和w,這里有很好的解釋。

http://kyfxbl.iteye.com/blog/...

shardKey

需要mongodb做分布式,才會使用該屬性。

strict

默認(rèn)是enabled,如果實(shí)例中的域(field)在schema中不存在,那么這個(gè)域不會被插入到數(shù)據(jù)庫。

var ThingSchema = new Schema({a:String});
var ThingModel = db.model("Thing",SchemaSchema);
var thing = new Thing({iAmNotInTheThingSchema:true});
thing.save();//iAmNotInTheThingSchema這個(gè)屬性將無法被存儲

// 通過doc.set()設(shè)置也會受到影響。
var thingSchema = new Schema({..})
var Thing = mongoose.model("Thing", thingSchema);
var thing = new Thing;
thing.set("iAmNotInTheSchema", true);
thing.save(); // iAmNotInTheSchema is not saved to the db

如果取消嚴(yán)格選項(xiàng),iAmNotInTheThingSchema將會被存入數(shù)據(jù)庫

var thingSchema = new Schema({..}, { strict: false });
var thing = new Thing({ iAmNotInTheSchema: true });
thing.save(); // iAmNotInTheSchema is now saved to the db!!

該選項(xiàng)也可以在Model級別使用,通過設(shè)置第二個(gè)參數(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)問題將會拋出錯誤而不是拋棄不合適的數(shù)據(jù)。

注意:

不要設(shè)置為false除非你有充分的理由。

在mongoose v2里默認(rèn)是false。

在實(shí)例上設(shè)置的任何鍵值對如果再schema中不存在對應(yīng)的,將會被忽視。

var thingSchema = new Schema({..})
var Thing = mongoose.model("Thing", thingSchema);
var thing = new Thing;
thing.iAmNotInTheSchema = true;
thing.save(); // iAmNotInTheSchema 不會保存到數(shù)據(jù)庫。
toJSON

和toObject類似,選擇這個(gè)選項(xiàng)為true后,但是只有當(dāng)實(shí)例調(diào)用了toJSON方法后,才會起作用。

var schema = new Schema({ name: String });
schema.path("name").get(function (v) { 
    return v + " is my name";
});

schema.set("toJSON", { getters: true, virtuals: false });
var M = mongoose.model("Person", schema);
var m = new M({ name: "Max Headroom" });
console.log(m.toObject()); // { _id: 504e0cd7dd992d9be2f20b6f, name: "Max Headroom" }
console.log(m.toJSON()); // { _id: 504e0cd7dd992d9be2f20b6f, name: "Max Headroom is my name" }
console.log(JSON.stringify(m)); // { "_id": "504e0cd7dd992d9be2f20b6f", "name": "Max Headroom is my name" }

可以看出,配置屬性name對toObject沒影響,對toJSON有影響。

toObject

選擇這個(gè)選項(xiàng)為true后,默認(rèn)對這個(gè)schema所有的實(shí)例都有作用。不需要實(shí)例手動調(diào)用。

var schema = new Schema({ name: String });
schema.path("name").get(function (v) {  
    return v + " is my name";
});

schema.set("toObject", { getters: true });
var M = mongoose.model("Person", schema);
var m = new M({ name: "Max Headroom" });
console.log(m); // { _id: 504e0cd7dd992d9be2f20b6f, name: "Max Headroom is my name" }

較上面不同的是,沒有virtuals: false這個(gè)設(shè)置。

typeKey

在mongoose里,如果schema里有個(gè)對象,并且這個(gè)對象有個(gè)type鍵,mongoose將會將這個(gè)作為一種類型聲明。

// Mongoose 認(rèn)為loc字段的類型是一個(gè)字符串,而不是有type這個(gè)字段 
var schema = new Schema({ loc: { type: String, coordinates: [Number] } });

然而,對于一些應(yīng)用來說,type字段是必要的。那么可以通過typeKey來設(shè)置。

var schema = new Schema({ 
    // Mongoose 這時(shí)候認(rèn)為loc字段有兩個(gè)鍵,一個(gè)是type,一個(gè)是coordinates  
    loc: { type: String, coordinates: [Number] },  
    // Mongoose 這時(shí)候認(rèn)為name字段的類型是字符串。  
    name: { $type: String }
},{ typeKey: "$type" }); // "$type"鍵意味著這是一個(gè)類型宣告,而不是默認(rèn)的type
validateBeforeSave

默認(rèn)得,文檔被保存到數(shù)據(jù)庫的時(shí)候會自動驗(yàn)證,這是為了防止無效的文檔。如果想要手動處理驗(yàn)證,并且能保存不通過驗(yàn)證的文檔,可以設(shè)置這個(gè)選項(xiàng)為false。

var schema = new Schema({ name: String });
schema.set("validateBeforeSave", false);
schema.path("name").validate(function (value) {   
    return v != null;
});
var M = mongoose.model("Person", schema);
var m = new M({ name: null });
m.validate(function(err) { 
    console.log(err); // 將會告訴你null不被允許
});
m.save(); // 盡管數(shù)據(jù)無效,但是仍然可以保存。
versionKey

版本鎖設(shè)置在每一個(gè)文檔(document)上,由mogoose生成。默認(rèn)的值是__v,但是可以自定義。

var schema = new Schema({ name: "string" });
var Thing = mongoose.model("Thing", schema);
var thing = new Thing({ name: "mongoose v3" });
thing.save(); // { __v: 0, name: "mongoose v3" }

// 自定義版本鎖
new Schema({..}, { versionKey: "_somethingElse" });
var Thing = mongoose.model("Thing", schema);
var thing = new Thing({ name: "mongoose v3" });
thing.save(); // { _somethingElse: 0, name: "mongoose v3" }

不要將這個(gè)選項(xiàng)設(shè)置為false除非你知道你在做什么。

skipVersioning

http://aaronheckmann.tumblr.c...

按照這里的說法,大致是說,加入在一個(gè)博客系統(tǒng)中,一個(gè)人所有的評論是一個(gè)數(shù)組,那么所有的評論是有索引的,比如某一條評論的body,comments.3.body,這里3是索引。假如一個(gè)評論者(A)想要修改自己的評論,但是此時(shí)另一個(gè)評論者(B)刪除(或其他操作)了自己的評論,那么對A的索引可能會造成變化,此時(shí)對A的操作會發(fā)生錯誤。

為了改變這個(gè)問題,mongoose v3添加了version key配置。無論什么時(shí)候修改一個(gè)數(shù)組潛在地改變數(shù)組元素位置,這個(gè)version key(__V)的值會加1。在where條件中也需要添加__v條件,如果能通過(數(shù)組索引沒改變),就可以修改,例如:

posts.update(
    { _id: postId, __v: verionNumber } ,
    { $set: { "comments.3.body": updatedText }}
);

如果在更新之前刪除了評論,那么就會發(fā)生錯誤。

post.save(function (err) { 
    console.log(err); // Error: No matching document found.
});
timestamps

如果在schema設(shè)置這個(gè)選項(xiàng),createdAt和updatedAt域?qū)蛔詣犹砑拥奈臋n中。它們默認(rèn)的類型是Date,默認(rèn)的名字是createdAt和updatedAt,不過我們可以自己修改。

var thingSchema = new Schema({..}, { timestamps: { createdAt: "created_at" } });
var Thing = mongoose.model("Thing", thingSchema);
var thing = new Thing();
thing.save(); // created_at & updatedAt將會被包含在文檔。
useNestedStrict

在mongoos 4, update()和findOneAndUpdate()方法只檢查頂級schema的strict的選項(xiàng)設(shè)置。

var childSchema = new Schema({}, { strict: false });// 這里parentSchema是topSchema,而childSchema是subSchema。
var parentSchema = new Schema({ child: childSchema }, { strict: "throw" });
var Parent = mongoose.model("Parent", parentSchema);
Parent.update({}, { "child.name": "Luke Skywalker" }, function(error) {  
    // 發(fā)生錯誤因?yàn)閜arentSchema設(shè)置了strict: "throw"}
    // 即使childSchema設(shè)置了{(lán)strict: false}
});
var update = { "child.name": "Luke Skywalker" };
var opts = { strict: false };
Parent.update({}, update, opts, function(error) { 
    // 這個(gè)可以通過因?yàn)橹貙懥藀arentSchema的strict選項(xiàng)
});

如果設(shè)置了useNestedStrict為true,mogoose在更新時(shí)使用childSchema的strict選項(xiàng)。

var childSchema = new Schema({}, { strict: false });
var parentSchema = new Schema({ child: childSchema },  { strict: "throw", useNestedStrict: true });
var Parent = mongoose.model("Parent", parentSchema);
Parent.update({}, { "child.name": "Luke Skywalker" }, function(error) { 
    // 可以更新
});
retainKeyOrder

默認(rèn)得,mongoose會轉(zhuǎn)換實(shí)體中鍵的順序。比如

new Model({ first: 1, second: 2 })

將會在MongoDB中存儲為{ second: 2, first: 1 };這帶來了極大的不方便。

Mongoose v4.6.4 有一個(gè)retainKeyOrder選項(xiàng)確保mongoose不會改變鍵的順序。

參考

http://cnodejs.org/topic/504b...

http://www.nodeclass.com/api/...

http://mongoosejs.com/docs/gu...

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/19086.html

相關(guān)文章

  • Mongoose增查改刪學(xué)習(xí)筆記

    摘要:查詢條件控制返回的字段控制選項(xiàng)回調(diào)函數(shù)。改查詢條件需要修改的數(shù)據(jù),不能修改主鍵控制選項(xiàng)回調(diào)函數(shù),返回的是受影響的行數(shù)。執(zhí)行查詢,回調(diào)函數(shù)。使用鏈?zhǔn)秸Z句時(shí),可以在之后接執(zhí)行查詢,并指定回調(diào)函數(shù)。 初學(xué)Node.js接觸到MongoDB數(shù)據(jù)庫,閱讀資料中推薦的都是Mongoose模塊,可以更加方便的對數(shù)據(jù)庫進(jìn)行操作,便開始接觸Mongoose。在學(xué)習(xí)時(shí)碰到許多基礎(chǔ)問題,查閱了許多資料理來理...

    lookSomeone 評論0 收藏0
  • MongoDB學(xué)習(xí)筆記

    背景 學(xué)習(xí)MongoDB,并做筆記整理,以便于用到時(shí)查看。 MogoDB NoSQL Database(JS) 使用方便,想存就存,相取就取 是MEAN中的M(數(shù)據(jù)) 安裝 https://www.mongodb.com/downl... 選擇相應(yīng)系統(tǒng)安裝包 安裝mongoose 創(chuàng)建一個(gè)文件夾,并npm init --yes,創(chuàng)建package.js npm install mongoos...

    April 評論0 收藏0
  • mongodb學(xué)習(xí)筆記(3)--mongoose實(shí)現(xiàn)curd

    簡介 mongoose實(shí)現(xiàn)curd 初始化 showImg(https://segmentfault.com/img/bVbhflF?w=307&h=211); npm init cnpm install mongoose --save-dev index.js const mongoose = require(mongoose); mongoose.connect(mongodb://127....

    ShowerSun 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<