Population应该尽量少用吗?我在nodeclub的models中没看到使用ref来做关联,那读取数据的时候怎么做到一次查询
如果是多表查询的话是不行的,具体要在程序里面实现。 Population貌似必须2个表之间有_id关联,可是很多情况貌似满足不了需求。 所以要么在存表的时候给一定的冗余,要么所有的关联在代码中实现(注意一下效率,避免内存溢出)
个人理解,不对勿喷
个人感觉是mongo数据库的集合设计问题 - 内嵌文档 vs. DBRef。如果有两个实体,比如User和Team,约束为M:1(一个Team下可以包含多个User,一个User只能属于一个Team),这种情况下,可以设计为DBRef,集合中数据可能为: User:
{ "_id" : ObjectId("id_of_user#1"), "teamId" : [ { "$ref" : "Team", "$id" : ObjectId("id_of_team#1") } ]} { "_id" : ObjectId("id_of_user#2"), "teamId" : [ { "$ref" : "Team", "$id" : ObjectId("id_of_team#1") } ]}
Team:
{ "_id" : ObjectId("id_of_team#1") }
在mongoose中,要定义上述关系,可以这样来定义Schema:
var User = new Schema({ team: { type: Schema.Types.ObjectId, ref: 'Team' }, });
当然还需要导出Schema为Model (mongoose.model(‘User’, User);)。定义Team:
var Team = new Schema({ team: { type: Schema.Types.ObjectId, ref: 'Team' }, });
从数据库里查询User时可以一并查出Team对象:
User.findOne('id_of_some_user') .populate('team') .exec(function (err, user) { // ... });
这样,user.team就不会是一个ObjectId对象。需要说明的是: 1). 查看数据库会发现,mongoose弄出来的数据和mongodb的官方做法不一样,比如它不是
{ "_id" : ObjectId("id_of_user#1"), "teamId" : [ { "$ref" : "Team", "$id" : ObjectId("id_of_team#1") } ]}
而是
{ "_id" : ObjectId("id_of_user#1"), "teamId" : ObjectId("id_of_team#1") }
这是因为通过Schema的定义,数据的关联关系已经表达得很清楚了。当然,这也可能成为你考虑是否使用mongoose的一个因素(数据活得比应用久,说不定你要考虑换框架呢)。
2). populate会向mongodb数据库发起新的数据库查询,即额外的查询请求(mongodb中并没有关系型数据库的表JOIN操作)。
@GuoZhang 谢谢回复 这样写 var User = new Schema({ team: [{ type: Schema.Types.ObjectId, ref: 'Team' }], }); 生成的就是 { "_id" : ObjectId("id_of_user#1"), "teamId" : [ { "$ref" : "Team", "$id" : ObjectId("id_of_team#1") } ]} 这样的 既然. populate会向mongodb数据库发起新的数据库查询 ,那应该直接尽量自己写程序解决,populate只是简化了我们查询
var User = new Schema({
team: [{ type: Schema.Types.ObjectId, ref: 'Team' }],
});
不用populate 自己又如何写呢?难道拿到id再查询一次数据库,那结果不是还一样,如果是查询很多数据,要全部遍历一次分别拿id去查一下吗?我只是想知道大家不用populate 怎么处理的 还有populate 这个好像只能查询直接关联的model,关联的model的关联model就不能查询出来了,怎么办呢?
@hanzel21cn 你说的所在的关联在代码中实现是如何做的?可以做到多级关联查询吗?
@GuoZhang 知道如何实现多级关联查询吗?
找到了,最新版的mongoose支持了deep-populate 官方文档: deep-populate
CNode 社区为国内最专业的 Node.js 开源技术社区,致力于 Node.js 的技术研究。
如果是多表查询的话是不行的,具体要在程序里面实现。 Population貌似必须2个表之间有_id关联,可是很多情况貌似满足不了需求。 所以要么在存表的时候给一定的冗余,要么所有的关联在代码中实现(注意一下效率,避免内存溢出)
个人理解,不对勿喷
个人感觉是mongo数据库的集合设计问题 - 内嵌文档 vs. DBRef。如果有两个实体,比如User和Team,约束为M:1(一个Team下可以包含多个User,一个User只能属于一个Team),这种情况下,可以设计为DBRef,集合中数据可能为: User:
Team:
在mongoose中,要定义上述关系,可以这样来定义Schema:
当然还需要导出Schema为Model (mongoose.model(‘User’, User);)。定义Team:
从数据库里查询User时可以一并查出Team对象:
这样,user.team就不会是一个ObjectId对象。需要说明的是: 1). 查看数据库会发现,mongoose弄出来的数据和mongodb的官方做法不一样,比如它不是
这是因为通过Schema的定义,数据的关联关系已经表达得很清楚了。当然,这也可能成为你考虑是否使用mongoose的一个因素(数据活得比应用久,说不定你要考虑换框架呢)。
2). populate会向mongodb数据库发起新的数据库查询,即额外的查询请求(mongodb中并没有关系型数据库的表JOIN操作)。
@GuoZhang 谢谢回复 这样写
var User = new Schema({team: [{ type: Schema.Types.ObjectId, ref: 'Team' }],});生成的就是{ "_id" : ObjectId("id_of_user#1"), "teamId" : [ { "$ref" : "Team", "$id" : ObjectId("id_of_team#1") } ]}这样的 既然. populate会向mongodb数据库发起新的数据库查询 ,那应该直接尽量自己写程序解决,populate只是简化了我们查询不用populate 自己又如何写呢?难道拿到id再查询一次数据库,那结果不是还一样,如果是查询很多数据,要全部遍历一次分别拿id去查一下吗?我只是想知道大家不用populate 怎么处理的 还有populate 这个好像只能查询直接关联的model,关联的model的关联model就不能查询出来了,怎么办呢?
@hanzel21cn 你说的所在的关联在代码中实现是如何做的?可以做到多级关联查询吗?
@GuoZhang 知道如何实现多级关联查询吗?
找到了,最新版的mongoose支持了deep-populate 官方文档: deep-populate