如何使用 Mongoose 在 mongoDB 中填充 3 个集合
Posted
技术标签:
【中文标题】如何使用 Mongoose 在 mongoDB 中填充 3 个集合【英文标题】:How to populate in 3 collection in mongoDB with Mongoose 【发布时间】:2019-01-14 10:13:36 【问题描述】:我有三个集合,例如User
、Program
和`Agenda。这些模型如下。
用户模型
const mongoose = require('mongoose');
const UserSchema = mongoose.Schema(
name: type:String,
email: type:String
,timestamps:true
);
module.exports = mongoose.model('User', UserSchema);
程序模型
const mongoose = require('mongoose');
const NoteSchema = mongoose.Schema(
name: type:String,
timefrom: type:Date,
timeto: type:Date,
status: type:String,
venue: type:String,
timetype: type:Number,
userid:type:mongoose.Schema.Types.ObjectId,ref : 'User', required: true,
logo :type:String,default: 'programe'
,timestamps:true
);
module.exports = mongoose.model('Program', NoteSchema);
议程模型
const mongoose = require('mongoose');
const AgendaSchema = mongoose.Schema(
name: type:String,
timefrom: type:Date,
timeto: type:Date,
status: type:String,
proorder: type:String,
proid:type:mongoose.Schema.Types.ObjectId,ref : 'Program', required: true
,
timestamps:true
);
module.exports = mongoose.model('Agenda', AgendaSchema);
现在我只获得议程和节目数据。
议程控制者
// Retrieve and return all agenda from the database.
exports.findAll = (req, res) =>
Agenda.find()
.populate('proid')
//.populate('userid')
.then(agendas =>
res.send(agendas);
).catch(err =>
res.status(500).send(
message: err.message || "Some error occurred while retrieving agenda."
);
);
;
当我转到此 URL 和 GET
方法时,我想填充 agenda
文档(完成)、相关的 program
文档(完成)和相关的 user
文档(我想要的)?
想要的查询是这样的
SELECT *
FROM users, programs, agendas
WHERE agendas.proid = programs.id AND programs.userid = users.id
【问题讨论】:
你的mongodb版本是多少? MongoDB 版本是4.0.0
【参考方案1】:
您可以使用$lookup
聚合
Agenda.aggregate([
"$lookup":
"from": Program.collection.name,
"let": "proid": "$proid" ,
"pipeline": [
"$match": "$expr": "$eq": [ "$_id", "$$proid" ] ,
"$lookup":
"from": User.collection.name,
"let": "userid": "$userid" ,
"pipeline": [
"$match": "$expr": "$eq": [ "$_id", "$$userid" ] ,
],
"as": "userid"
,
"$unwind": "$userid"
],
"as": "proid"
,
"$unwind": "$proid"
])
或使用填充
Agenda.find()
.populate([ path: 'proid', populate: path: 'userid' ])
两者都会给你相同的结果
【讨论】:
populate
看起来更干净
@Hassaan 但是你不能使用populate
中的数据,从长远来看当然$lookup
是更好的解决方案
不成功,显示为较早的结果(仅议程数据和节目数据,不显示用户数据)。
干得好!谢谢@Anthony Winzlet
@Anthony Winzlet,我可以从 pragrams 中获取所有三个集合的列表吗?这里我想通过localhost:3000/programes/id=1
GET
获取所有详细信息(这里我们可以通过填充轻松获取程序和用户详细信息,例如文档,但是如何获取议程详细信息,我们应该通过给定程序选择所有议程文档id
)?【参考方案2】:
您可以使用.populate()
和 populate : path : 'field'
。
示例:
Agenda.find(). //Collection 1
populate(path:'proid', //Collection 2
populate:path:'userid' //Collection 3
)
.exec();
4个集合后,需要识别型号,如果不能错 示例:
Agenda.find(). //Collection 1
populate(path:'proid', //Collection 2
populate:path:'userid', //Collection 3
populate:path:'otherFiel', model: Collection //Collection 4 and more
)
.exec();
最后,如果您只想获取某个 Collection 的某些字段,您可以使用属性select
示例:
Agenda.find().
populate(path:'proid', select:'name status venue'
populate:path:'userid'
)
.exec();
【讨论】:
以上是关于如何使用 Mongoose 在 mongoDB 中填充 3 个集合的主要内容,如果未能解决你的问题,请参考以下文章
如何在 typescript 中使用 mongoose 在 mongodb 中插入数据?
如何使用 Mongoose 在 mongoDB 中填充 3 个集合
如何在 mongoose/mongodb 查询子文档中使用 mapreduce?
如何在 mongoose/mongodb 查询子文档中使用 mapreduce?