资讯专栏INFORMATION COLUMN

[转]mongodb中的populate方法

ranwu / 1511人阅读

摘要:使用可以实现在一个中填充其他的。表示关联注意被关联的的必须是和才有效。封装了很多查询的方法,使得对数据库的操作变得简单啦。这里分享一下方法用法。类型的时,格式如为表示不填充,为时表示填充。类型,可选,指定附加的查询条件。

Mongoose 是 MongoDB 的 ODM(Object Document Mapper)。

什么是ODM? 其实和ORM(Object Relational Mapper)是同类型的工具。都是将数据库的数据转化为代码对象的库,使用转化后的对象可以直接对数据库的数据进行CRUD(增删改查)。

MongoDB 是文档型数据库(Document Database),不是关系型数据库(RelationalDatabase)。而Mongoose可以将 MongonDB 数据库存储的文档(documents)转化为 javascript对象,然后可以直接进行数据的增删改查。

因为MongoDB是文档型数据库,所以它没有关系型数据库joins(数据库的两张表通过"外键",建立连接关系。) 特性。也就是在建立数据的关联时会比较麻烦。为了解决这个问题,Mongoose封装了一个Population功能。使用Population可以实现在一个 document 中填充其他 collection(s)document(s)

在定义Schema的时候,如果设置某个 field 关联另一个Schema,那么在获取 document 的时候就可以使用 Population 功能通过关联Schema的 field 找到关联的另一个 document,并且用被关联 document 的内容替换掉原来关联字段(field)的内容。

接下来分享下:Query#populate Model#populate Document#populate的用法

先建立三个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);

在上述的例子中,创建了三个 Models:UserPostComment
User 的属性 post`,对应是一个 ObjectId 的数组。ref表示关联Post(注意: 被关联的model的 type 必须是ObjectId, Number, String, 和 Buffer 才有效)。
Post的属性 poster 和 comments 分别关联User和Comment。
Comment的属性 post 和 commenter 分别关联Post和User。
三个 Models 的关系:一个 user--has many-->post。一个 post--has one-->user,has many-->comment。一个 comment--has one-->post 和 user。
创建一些数据到数据库:

// 连接数据库
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) {
            });
        });
    });
}

数据的准备就绪后,接下来就是探索populate方法:

Query#populate

什么Query? Query(查询),可以快速和简单的从MongooDB查找出相应的 document(s)。 Mongoose封装了很多查询的方法,使得对数据库的操作变得简单啦。这里分享一下populate方法用法。

语法: Query.populate(path, [select], [model], [match], [options])

参数:
path
  类型StringObject
  String类型的时, 指定要填充的关联字段,要填充多个关联字段可以以空格分隔。
  Object类型的时,就是把 populate 的参数封装到一个对象里。当然也可以是个数组。下面的例子中将会实现。

select
  类型ObjectString,可选,指定填充document 中的哪些字段。
  Object类型的时,格式如:{name: 1, _id: 0},为0表示不填充,为1时表示填充。
  String类型的时,格式如:"name -_id",用空格分隔字段,在字段名前加上-表示不填充。详细语法介绍query-select

model
  类型Model,可选,指定关联字段的 model,如果没有指定就会使用Schema的ref。
match
  类型Object,可选,指定附加的查询条件。
options
  类型Object,可选,指定附加的其他查询选项,如排序以及条数限制等等。

填充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
        });
    });

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/18935.html

相关文章

  • Mongoose 之 Population 使用

    摘要:使用可以实现在一个中填充其他的。表示关联注意被关联的的必须是和才有效。类型的时,格式如为表示不填充,为时表示填充。以键值对的形式表示。回调函数,接收两个参数,错误和填充完的。参考数据库的最简单实现使用之原文链接 Mongoose 是 MongoDB 的 ODM(Object Document Mapper)。 什么是ODM? 其实和ORM(Object Relational Mapp...

    timger 评论0 收藏0
  • Mongoose简要API

    摘要:是在环境下对进行便捷操作的对象模型工具因此,要使用,则必须安装环境以及数据库。使操作更简单便捷。找到记录,并且将递增,返回后的为之前的。这个属性很有用,对数字直接进行增减。,要返回的字段与的第二个参数一致。 Mongoose是在node.js环境下对mongodb进行便捷操作的对象模型工具 因此,要使用mongoose,则必须安装node.js环境以及mongodb数据库。mongoo...

    王岩威 评论0 收藏0
  • 在线考试系统(vue2 + elementui + express4 + MongoDB

    摘要:在实际开发过程中发现,考试系统各个表集合都是需要关联,这种非关系型数据库,做起来反而麻烦了不少。数据中既有试卷的信息,也有很多题目。题目都属于该试卷,改试卷又属于当前登录系统的老师即创建试卷的老师。 这是我毕业项目,从0到1,前后台独立开发完成。功能不多,在此记录,温故而知新!项目github地址:https://github.com/FinGet/Exam ,博客地址:https:/...

    warmcheng 评论0 收藏0
  • 聊聊毕业设计系列 --- 系统实现

    摘要:七牛云接入本系统的图片,音视频是放在七牛云,所以需要接入七牛云。在服务端通过接口请求来获取七牛云上传,客户端获取到七牛云,通过不同方案将带上。 效果展示 showImg(https://user-gold-cdn.xitu.io/2018/8/26/16576a709bd02f5f?w=1409&h=521&f=gif&s=30128195); showImg(https://user...

    null1145 评论0 收藏0
  • 聊聊毕业设计系列 --- 系统实现

    摘要:七牛云接入本系统的图片,音视频是放在七牛云,所以需要接入七牛云。在服务端通过接口请求来获取七牛云上传,客户端获取到七牛云,通过不同方案将带上。 效果展示 showImg(https://user-gold-cdn.xitu.io/2018/8/26/16576a709bd02f5f?w=1409&h=521&f=gif&s=30128195); showImg(https://user...

    qpal 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<