亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

Mongoose 之 Population 使用

timger / 2194人閱讀

摘要:使用可以實(shí)現(xiàn)在一個(gè)中填充其他的。表示關(guān)聯(lián)注意被關(guān)聯(lián)的的必須是和才有效。類型的時(shí),格式如為表示不填充,為時(shí)表示填充。以鍵值對(duì)的形式表示?;卣{(diào)函數(shù),接收兩個(gè)參數(shù),錯(cuò)誤和填充完的。參考數(shù)據(jù)庫(kù)的最簡(jiǎn)單實(shí)現(xiàn)使用之原文鏈接

Mongoose 是 MongoDB 的 ODM(Object Document Mapper)

什么是ODM? 其實(shí)和ORM(Object Relational Mapper)是同類型的工具。都是將數(shù)據(jù)庫(kù)的數(shù)據(jù)轉(zhuǎn)化為代碼對(duì)象的庫(kù),使用轉(zhuǎn)化后的對(duì)象可以直接對(duì)數(shù)據(jù)庫(kù)的數(shù)據(jù)進(jìn)行CRUD(增刪改查)。

MongoDB 是文檔型數(shù)據(jù)庫(kù)(Document Database),不是關(guān)系型數(shù)據(jù)庫(kù)(Relational Database)。而Mongoose可以將 MongonDB 數(shù)據(jù)庫(kù)存儲(chǔ)的文檔(documents)轉(zhuǎn)化為 javascript 對(duì)象,然后可以直接進(jìn)行數(shù)據(jù)的增刪改查。

因?yàn)?b>MongoDB是文檔型數(shù)據(jù)庫(kù),所以它沒(méi)有關(guān)系型數(shù)據(jù)庫(kù)joins(數(shù)據(jù)庫(kù)的兩張表通過(guò)"外鍵",建立連接關(guān)系。) 特性。也就是在建立數(shù)據(jù)的關(guān)聯(lián)時(shí)會(huì)比較麻煩。為了解決這個(gè)問(wèn)題,Mongoose封裝了一個(gè)Population功能。使用Population可以實(shí)現(xiàn)在一個(gè) document 中填充其他 collection(s)document(s)。

在定義Schema的時(shí)候,如果設(shè)置某個(gè) field 關(guān)聯(lián)另一個(gè)Schema,那么在獲取 document 的時(shí)候就可以使用 Population 功能通過(guò)關(guān)聯(lián)Schema的 field 找到關(guān)聯(lián)的另一個(gè) document,并且用被關(guān)聯(lián) document 的內(nèi)容替換掉原來(lái)關(guān)聯(lián)字段(field)的內(nèi)容。

接下來(lái)分享下:Query#populate Model#populate Document#populate的用法

先建立三個(gè)SchemaModel:

var mongoose = require("mongoose");
var Schema   = mongoose.Schema;

var UserSchema = new Schema({
    name  : { type: String, unique: true },
    posts : [{ type: Schema.Types.ObjectId, ref: "Post" }]
});
var User = mongoose.model("User", UserSchema);

var PostSchema = new Schema({
    poster   : { type: Schema.Types.ObjectId, ref: "User" },
    comments : [{ type: Schema.Types.ObjectId, ref: "Comment" }],
    title    : String,
    content  : String
});
var Post = mongoose.model("Post", PostSchema);

var CommentSchema = new Schema({
    post      : { type: Schema.Types.ObjectId, ref: "Post" },
    commenter : { type: Schema.Types.ObjectId, ref: "User" },
    content   : String
});
var Comment = mongoose.model("Comment", CommentSchema);

在上述的例子中,創(chuàng)建了三個(gè) Models:User,PostComment。

User 的屬性 posts,對(duì)應(yīng)是一個(gè) ObjectId 的數(shù)組。ref表示關(guān)聯(lián)Post(注意: 被關(guān)聯(lián)的model的 type 必須是 ObjectId, Number, String, 和 Buffer 才有效)。

Post的屬性 postercomments 分別關(guān)聯(lián)UserComment

Comment的屬性 postcommenter 分別關(guān)聯(lián)PostUser。

三個(gè) Models 的關(guān)系:一個(gè) user--has many-->post。一個(gè) post--has one-->user,has many-->comment。一個(gè) comment--has one-->post 和 user。

創(chuàng)建一些數(shù)據(jù)到數(shù)據(jù)庫(kù):

// 連接數(shù)據(jù)庫(kù)
mongoose.connect("mongodb://localhost/population-test", function (err){
    if (err) throw err;
    createData();
});

function createData() {

    var userIds    = [new ObjectId, new ObjectId, new ObjectId];
    var postIds    = [new ObjectId, new ObjectId, new ObjectId];
    var commentIds = [new ObjectId, new ObjectId, new ObjectId];

    var users    = [];
    var posts    = [];
    var comments = [];

    users.push({
        _id   : userIds[0],
        name  : "aikin",
        posts : [postIds[0]]
    });
    users.push({
        _id   : userIds[1],
        name  : "luna",
        posts : [postIds[1]]
    });
    users.push({
        _id   : userIds[2],
        name  : "luajin",
        posts : [postIds[2]]
    });

    posts.push({
        _id      : postIds[0],
        title    : "post-by-aikin",
        poster   : userIds[0],
        comments : [commentIds[0]]
    });
    posts.push({
        _id      : postIds[1],
        title    : "post-by-luna",
        poster   : userIds[1],
        comments : [commentIds[1]]
    });
    posts.push({
        _id      : postIds[2],
        title    : "post-by-luajin",
        poster   : userIds[2],
        comments : [commentIds[2]]
    });

    comments.push({
        _id       : commentIds[0],
        content   : "comment-by-luna",
        commenter : userIds[1],
        post      : postIds[0]
    });
    comments.push({
        _id       : commentIds[1],
        content   : "comment-by-luajin",
        commenter : userIds[2],
        post      : postIds[1]
    });
    comments.push({
        _id       : commentIds[2],
        content   : "comment-by-aikin",
        commenter : userIds[1],
        post      : postIds[2]
    });

    User.create(users, function(err, docs) {
        Post.create(posts, function(err, docs) {
            Comment.create(comments, function(err, docs) {
            });
        });
    });
}

數(shù)據(jù)的準(zhǔn)備就緒后,接下來(lái)就是探索populate方法:

1. Query#populate

什么Query? Query(查詢),可以快速和簡(jiǎn)單的從MongooDB查找出相應(yīng)的 document(s)。 Mongoose 封裝了很多查詢的方法,使得對(duì)數(shù)據(jù)庫(kù)的操作變得簡(jiǎn)單啦。這里分享一下populate方法用法。

語(yǔ)法:

**`Query.populate(path, [select], [model], [match], [options])`**

參數(shù):

path

  類型:StringObject
  String類型的時(shí), 指定要填充的關(guān)聯(lián)字段,要填充多個(gè)關(guān)聯(lián)字段可以以空格分隔。
  Object類型的時(shí),就是把 populate 的參數(shù)封裝到一個(gè)對(duì)象里。當(dāng)然也可以是個(gè)數(shù)組。下面的例子中將會(huì)實(shí)現(xiàn)。

select

  類型:ObjectString,可選,指定填充 document 中的哪些字段。
  Object類型的時(shí),格式如:{name: 1, _id: 0},為0表示不填充,為1時(shí)表示填充。
  String類型的時(shí),格式如:"name -_id",用空格分隔字段,在字段名前加上-表示不填充。詳細(xì)語(yǔ)法介紹 query-select

model

  類型:Model,可選,指定關(guān)聯(lián)字段的 model,如果沒(méi)有指定就會(huì)使用Schemaref

match

  類型:Object,可選,指定附加的查詢條件。

options

  類型:Object,可選,指定附加的其他查詢選項(xiàng),如排序以及條數(shù)限制等等。

填充Userposts字段:

//填充所有 users 的 posts
User.find()
    .populate("posts", "title", null, {sort: { title: -1 }})
    .exec(function(err, docs) {
        console.log(docs[0].posts[0].title); // post-by-aikin
    });

//填充 user "luajin"的 posts
User.findOne({name: "luajin"})
    .populate({path: "posts", select: { title: 1 }, options: {sort: { title: -1 }}})
    .exec(function(err, doc) {
        console.log(doc.posts[0].title);  // post-by-luajin
    });

//這里的 populate 方法傳入的參數(shù)形式不同,其實(shí)實(shí)現(xiàn)的功能是一樣的,只是表示形式不一樣。

填充Postpostercomments字段:

Post.findOne({title: "post-by-aikin"})
    .populate("poster comments", "-_id")
    .exec(function(err, doc) {
        console.log(doc.poster.name);           // aikin
        console.log(doc.poster._id);            // undefined

        console.log(doc.comments[0].content);  // comment-by-luna
        console.log(doc.comments[0]._id);      // undefined
    });

Post.findOne({title: "post-by-aikin"})
    .populate({path: "poster comments", select: "-_id"})
    .exec(function(err, doc) {
        console.log(doc.poster.name);           // aikin
        console.log(doc.poster._id);            // undefined

        console.log(doc.comments[0].content);  // comment-by-luna
        console.log(doc.comments[0]._id);      // undefined
    });

//上兩種填充的方式實(shí)現(xiàn)的功能是一樣的。就是給 populate 方法的參數(shù)不同。
//這里要注意,當(dāng)兩個(gè)關(guān)聯(lián)的字段同時(shí)在一個(gè) path 里面時(shí), select 必須是 document(s)
//具有的相同字段。


//如果想要給單個(gè)關(guān)聯(lián)的字段指定 select,可以傳入數(shù)組的參數(shù)。如下:

Post.findOne({title: "post-by-aikin"})
    .populate(["poster", "comments"])
    .exec(function(err, doc) {
        console.log(doc.poster.name);          // aikin
        console.log(doc.comments[0].content);  // comment-by-luna
    });

Post.findOne({title: "post-by-aikin"})
    .populate([
        {path:"poster",   select: "-_id"},
        {path:"comments", select: "-content"}
    ])
    .exec(function(err, doc) {
        console.log(doc.poster.name);          // aikin
        console.log(doc.poster._id);           // undefined

        console.log(doc.comments[0]._id);      // 會(huì)打印出對(duì)應(yīng)的 comment id
        console.log(doc.comments[0].content);  // undefined
    });
2. Model#populate

Model(模型),是根據(jù)定義的 Schema 編譯成的抽象的構(gòu)造函數(shù)。models 的實(shí)例 documents,可以在數(shù)據(jù)庫(kù)中被保存和檢索。數(shù)據(jù)庫(kù)所有 document 的創(chuàng)建和檢索,都通過(guò) models 處理。

語(yǔ)法:

**`Model.populate(docs, options, [cb(err,doc)])`**

參數(shù):

docs

  類型:DocumentArray。單個(gè)需要被填充的 doucment 或者 document 的數(shù)組。

options

  類型:Object。以鍵值對(duì)的形式表示。
  keys:path select match model options,這些鍵對(duì)應(yīng)值的類型和功能,與上述Query#populate方法的參數(shù)相同。

[cb(err,doc)]

  類型:Function,回調(diào)函數(shù),接收兩個(gè)參數(shù),錯(cuò)誤err和填充完的doc(s)。

填充Postpostercomments字段以及commentscommenter字段:

Post.find({title: "post-by-aikin"})
    .populate("poster comments")
    .exec(function(err, docs) {

        var opts = [{
            path   : "comments.commenter",
            select : "name",
            model  : "User"
        }];

        Post.populate(docs, opts, function(err, populatedDocs) {
            console.log(populatedDocs[0].poster.name);                  // aikin
            console.log(populatedDocs[0].comments[0].commenter.name);  // luna
        });
    });
3. Document#populate

Document,每個(gè) document 都是其 Model 的一個(gè)實(shí)例,一對(duì)一的映射著 MongoDB 的 document。

語(yǔ)法:

**`Document.populate([path], [callback])`**

參數(shù):

path

  類型:StringObject。與上述Query#populate`方法的 path 參數(shù)相同。

callback

  類型:Function?;卣{(diào)函數(shù),接收兩個(gè)參數(shù),錯(cuò)誤err和填充完的doc(s)

填充Userposts字段:

User.findOne({name: "aikin"})
    .exec(function(err, doc) {

        var opts = [{
            path   : "posts",
            select : "title"
        }];

        doc.populate(opts, function(err, populatedDoc) {
            console.log(populatedDoc.posts[0].title);  // post-by-aikin
        });
    });

博文涉及的完整例子在 gist 上。(ps: gist 被已墻了。)

參考

mongoose-api-docs

數(shù)據(jù)庫(kù)的最簡(jiǎn)單實(shí)現(xiàn)

Mongoose 使用之 Population

原文鏈接

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/18758.html

相關(guān)文章

  • [轉(zhuǎn)]mongodb中的populate方法

    摘要:使用可以實(shí)現(xiàn)在一個(gè)中填充其他的。表示關(guān)聯(lián)注意被關(guān)聯(lián)的的必須是和才有效。封裝了很多查詢的方法,使得對(duì)數(shù)據(jù)庫(kù)的操作變得簡(jiǎn)單啦。這里分享一下方法用法。類型的時(shí),格式如為表示不填充,為時(shí)表示填充。類型,可選,指定附加的查詢條件。 Mongoose 是 MongoDB 的 ODM(Object Document Mapper)。 什么是ODM? 其實(shí)和ORM(Object Relational...

    ranwu 評(píng)論0 收藏0
  • 【譯】《精通使用AngularJS開(kāi)發(fā)Web App》(三)--- 深入scope,繼承結(jié)構(gòu),事件系

    摘要:比如,我們可以監(jiān)聽(tīng)事件由實(shí)例發(fā)出,然后在任何瀏覽器中就是變化的時(shí)候都會(huì)得到通知,如下所示每一個(gè)作用域?qū)ο蠖紩?huì)有這個(gè)方法,可以用來(lái)注冊(cè)一個(gè)作用域事件的偵聽(tīng)器。這個(gè)函數(shù)所扮演的偵聽(tīng)器在被調(diào)用時(shí)會(huì)有一個(gè)對(duì)象作為第一個(gè)參數(shù)。 上一篇:【譯】《精通使用AngularJS開(kāi)發(fā)Web App》(二) 下一篇:【譯】《精通使用AngularJS開(kāi)發(fā)Web App》(四) 書名:Mastering W...

    wind5o 評(píng)論0 收藏0
  • 4000字詳細(xì)說(shuō)明,推薦20個(gè)好用到爆的Pandas函數(shù)方法

    摘要:往期回顧教程實(shí)現(xiàn)社交網(wǎng)絡(luò)可視化,看看你的人脈影響力如何轉(zhuǎn)載字概括精髓,必知必會(huì)例注意字歸納總結(jié)帶你做數(shù)據(jù)預(yù)處理新聞字張圖,一鍵生成炫酷的動(dòng)態(tài)交互式圖表分享收藏點(diǎn)贊在看 今天分享幾個(gè)不為人知的pandas函數(shù),大家可能平時(shí)看到的不多,但是使用起來(lái)倒是非常的方便,也能夠幫助我們數(shù)據(jù)分析人員大...

    2501207950 評(píng)論0 收藏0
  • mongodb操作mongoose(一)

    摘要:更重要的是它將返回的字符串包裝成了對(duì)象,這在操作時(shí)要比直接使用字符串方便許多。今天就利用的官方文檔對(duì)它的標(biāo)準(zhǔn)操作進(jìn)行簡(jiǎn)單的分析。 NOSQL存儲(chǔ)作為一種與關(guān)系性數(shù)據(jù)庫(kù)完全不同的存儲(chǔ)方式,提供了靈活,大型,敏捷,可擴(kuò)展的存儲(chǔ)模式,并且在有著復(fù)雜的數(shù)據(jù)情形下性能完全不遜色于RDBMS,而作為NOSQL中流行程度較高的數(shù)據(jù)庫(kù),mongodb有著上手容易,數(shù)據(jù)查詢方式多樣等諸多特點(diǎn),所以也深受...

    KavenFan 評(píng)論0 收藏0
  • Python遺傳算法框架DEAP-Creating Types

    摘要:是一個(gè)遺傳算法框架,這里是它的簡(jiǎn)介。最小化問(wèn)題使用負(fù)值的的最大化問(wèn)題用正值。略種群種群橫線個(gè)體。這個(gè)種群是直接使用和函數(shù)來(lái)初始化的。個(gè)體之間分布在網(wǎng)格中每個(gè)格子包含一個(gè)個(gè)體。調(diào)用將會(huì)返回一個(gè)種群,個(gè)體是使用兩個(gè)索引可獲得的。 DEAP是一個(gè)python遺傳算法框架,這里是它的簡(jiǎn)介。DEAP documentation今天整理一下DEAP的概覽,大體了解一下它的流程。初學(xué),不嚴(yán)謹(jǐn),僅作為...

    Channe 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<