文档章节

Mongoose 使用之 Population

陈纪年
 陈纪年
发布于 2013/06/16 14:24
字数 1037
阅读 8359
收藏 8
点赞 2
评论 2

何为 Population

用过 MongoDB 的人应该都知道它是没有关系型数据库里的 join 特性的,这意味着当我们使用 MongoDB 读取某个 document 及其关联的 document 的字段的时候,变得尤为麻烦。

基于此,Mongoose 封装了一个 population 的功能,当你在定义 Schema 的时候指定了某个 field 是引用了另一个 Schema ,那么你在获取 document 的时候就可以使用 populate 方法让 Mongoose 帮你通过引用 Schema 和 id 找到关联的另一个 document,并且用该 document 的内容替换掉原来引用字段的内容,使引用的 ducoment 使用起来就像是内嵌的 document 一样方便。

定义带有引用字段的 Schema

首先,如果要使用这个功能,必须给你的“外键字段”定义 Mongoose 的“外键约束”(这里借用关系型数据库的术语,只是为了帮助理解)。假设我们有一个用户的 Schema ,其中有一个字段是followings,保存用户关注了的其他用户,类似微博。Mongoose 的 Schema 定义如下:

var mongoose = require('mongoose')
  , Schema = mongoose.Schema
  
var UserSchema = Schema({
  name    : String,
  followings : [{ type: Schema.Types.ObjectId, ref: 'User' }]
});
    
var User = mongoose.model('User', UserSchema);

保存引用字段

然后我们创建两个 User 实例,并且先将其中之一保存进数据库(为了产生 _id ):

var lily = new User({name: 'lily'})
   ,lucy = new User({name: 'lucy'});
lily.save(cb);

lily 保存成功后,我们再在回调函数 cb 中保存 lucy ,不过这个时候假设 lucy 关注了 lily:

function cb(err) {
    if(err) throw err;
    lucy.followings.push(lily._id);// line 1
    lucy.save(cb1);
}

这样就保存完成了。不过好像我们没用引用字段之前也是这么保存的吧?有没有更直接一点的?有,你其实可以将 line 1 的语句改成以下形式, Mongoose 也会自动帮你做内部解析的:

lucy.followings.push(lily);

这样看起来代码就更接近自然语言了,有点ORM的味道。

查询 document

当然,上面的例子可能对开发者来说没有什么太大的用处,那么就来看看 population 在获取 document 的时候能给我们带来什么好处吧。

假设我们现在要找到 lucy 的信息以及她所关注的用户,我们可以这样:

User.findOne({name: 'lucy'}).exec(cb2);

但是这样拿出来的 lucy 的 followings 是一组存储了 ObjectId 的数组,还得去一个个查找对应的用户,多麻烦啊。所以这个时候用 population 就简单多了,直接指定你想要 populate 哪个引用字段:

User.findOne({name: 'lucy'}).populate('followings').exec(cb2);

这样的话,在回调函数 cb2 中你得到的就是一个存储了若干个 User 对象的数组了。

populate 方法

populate 方法可以用在 document 上、 model 上或者是 query 对象上,这意味着你几乎可以在任何地方调用这个方法以填充你的引用字段。

当然,populate 方法在不同对象上参数不大一样,但是都接收一个option的参数,你可以用这些参数指定:

  • path: 以空格分隔的引用字段的名称
  • select: 填充引用 document 中的哪些字段
  • match: 可选,指定附加的查询条件
  • model: 可选,指定引用的 model
  • options: 可选,指定附加的其他查询选项,如排序以及条数限制等等

引用字段的类型

目前,Mongoose 只支持以下几种引用字段的类型:

  • ObjectId
  • Number
  • String
  • Buffer

而且自然而然,引用 document 的主键类型必须和引用字段类型相对应。在生产环境中,推荐主键类型和引用类型都使用 ObjectId ,一是因为 ObjectId 不包含业务含义,二是 ObjectId 不大可能重复,三是因为 Mongoose 默认生成的主键类型就是 ObjectId ,可以减少很多配置的操作。

更多信息请关注这里

© 著作权归作者所有

共有 人打赏支持
陈纪年
粉丝 3
博文 7
码字总数 5687
作品 0
广州
程序员
加载中

评论(2)

懦酷
假如某个集合里需要跟三四个其他集合关联(即:1对N)。。populate性能会不会很差了?
ifsc01
ifsc01
好文,学习了
mongoose 使用populate 需要注意的问题

So far we've created two Models. Our Person model has it's stories field set to an array of ObjectIds. The refoption is what tells Mongoose which model to use during population,......

造化玉碟
2014/06/24
0
0
Express + Mongoose 极简入门

Express + Mongoose 极简入门 今天尝试使用express + mongoose,构建了一个简单的Hello world,实现以下功能: 定义mongodb使用的Schema,一个User 访问/输出Hello world 访问/init向mongodb...

maweitao
2014/04/11
0
4
使用mongoose-auto-increment的问题记录

一直使用mongodb 3.2,mongoose-auto-increment 5.0.1和mongoose 5.0.1 都没有问题,有一天,使用mongodb 3.4就出问题了,在创建id自动增加的功能的时候,出错,代码如下: let autoIncremen...

zdhsoft
04/10
0
0
轻量级Web服务器Mongoose

Mongoose Web Server是一款易于使用的Web服务器,它可以嵌入到其它应用程序中,为其提供Web接口。 主要特写: 跨平台,支持 Windows、OS X 和 Linux 支持 CGI, SSL, SSI, Digest (MD5) 认证,...

mickelfeng
2016/09/30
55
0
Mongoose - 让NodeJS更容易操作Mongodb数据

Mongoose是什么 Mongoose是什么 Mongoose是MongoDB的一个对象模型工具,可以工作于异步环境下。 定义一个模型很容易: var Comments = new Schema({ title : String , body : String , date ...

maweitao
2014/04/11
345
0
Mongoose 4.4.17 发布,MongoDB 连接包

Mongoose 4.4.17 发布了,以下是本次发布值得关注的内容: docs: remove repetition in QueryStream docs #4147 hugoabonizio fix(document): dont double-validate doc array elements #414......

oschina
2016/05/14
726
0
Node.js开发入门—用MongoDB改造LoginDemo

这次的示例基于之前的LoginDemo(见使用cookie保持登录),我们引入MongoDB来保存用户数据。要运行这个示例,前提是MongoDB数据要正常运行(见Node.js开发入门——MongoDB与Mongoose)。示例...

foruok
2015/08/19
0
0
nodejs mongoose建模实践

一直以来mongoose学习都是比较麻烦的,mongoose-cli试图简化学习和测试mongoose部分,并通过app开发流程反思整个过程中业务逻辑部分如何抽象,以期简化开发与分层实现 app开发流程 如图 这里...

i5ting
2015/08/07
0
0
Node.JS -- Mongoose 快速入门

Mongoose时一个用于异步环境的MongoDB的对象模型。 前提条件 先确保本地已经安装了Node.js和一个可以连接上的MongoDB。 安装Mongoose Mongoose和其他的依赖模块一样安装,使用npm 命令: 连接...

米阳MeYoung
06/04
0
0
在BAE中使用mongoose操作mongodb

在BAE中使用mongoose操作mongodb 几乎网上所有的使用mongoose的例子都是长连接的方式,因为nodejs本身机制的关系,使用长连接一定程度上会提高性能,但是bae的免费mongodb不支持长链接,之前...

假正经哥哥
2014/10/11
0
2

没有更多内容

加载失败,请刷新页面

加载更多

下一页

SpringBoot | 第十章:Swagger2的集成和使用

前言 前一章节介绍了mybatisPlus的集成和简单使用,本章节开始接着上一章节的用户表,进行Swagger2的集成。现在都奉行前后端分离开发和微服务大行其道,分微服务及前后端分离后,前后端开发的...

oKong
今天
2
0
Python 最小二乘法 拟合 二次曲线

Python 二次拟合 随机生成数据,并且加上噪声干扰 构造需要拟合的函数形式,使用最小二乘法进行拟合 输出拟合后的参数 将拟合后的函数与原始数据绘图后进行对比 import numpy as npimport...

阿豪boy
今天
1
0
云拿 无人便利店

附近(上海市-航南路)开了家无人便利店.特意进去体验了一下.下面把自己看到的跟大家分享下. 经得现场工作人员同意后拍了几张照片.从外面看是这样.店门口的指导里强调:不要一次扫码多个人进入....

周翔
昨天
1
0
Java设计模式学习之工厂模式

在Java(或者叫做面向对象语言)的世界中,工厂模式被广泛应用于项目中,也许你并没有听说过,不过也许你已经在使用了。 简单来说,工厂模式的出现源于增加程序序的可扩展性,降低耦合度。之...

路小磊
昨天
161
1
npm profile 新功能介绍

转载地址 npm profile 新功能介绍 npm新版本新推来一个功能,npm profile,这个可以更改自己简介信息的命令,以后可以不用去登录网站来修改自己的简介了 具体的这个功能的支持大概是在6这个版...

durban
昨天
1
0
Serial2Ethernet Bi-redirection

Serial Tool Serial Tool is a utility for developing serial communications, custom protocols or device testing. You can set up bytes to send accordingly to your protocol and save......

zungyiu
昨天
1
0
python里求解物理学上的双弹簧质能系统

物理的模型如下: 在这个系统里有两个物体,它们的质量分别是m1和m2,被两个弹簧连接在一起,伸缩系统为k1和k2,左端固定。假定没有外力时,两个弹簧的长度为L1和L2。 由于两物体有重力,那么...

wangxuwei
昨天
0
0
apolloxlua 介绍

##项目介绍 apolloxlua 目前支持javascript到lua的翻译。可以在openresty和luajit里使用。这个工具分为两种模式, 一种是web模式,可以通过网页使用。另外一种是tool模式, 通常作为大规模翻...

钟元OSS
昨天
2
0
Mybatis入门

简介: 定义:Mybatis是一个支持普通SQL查询、存储过程和高级映射的持久层框架。 途径:MyBatis通过XML文件或者注解的形式配置映射,实现数据库查询。 特性:动态SQL语句。 文件结构:Mybat...

霍淇滨
昨天
2
0
开发技术瓶颈期,如何突破

前言 读书、学习的那些事情,以前我也陆续叨叨了不少,但总觉得 “学习方法” 就是一个永远在路上的话题。个人的能力、经验积累与习惯方法不尽相同,而且一篇文章甚至一本书都很难将学习方法...

_小迷糊
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部