我有Page
:
const PageSchema = new Schema({
children: [{type: mongoose.Schema.Types.ObjectId, ref: 'Page'}]
});
正如您所看到的,每个Page
都有一个children
数组,该数组也是Page
。
现在我需要做的是获取所有" main"页面并填充他们的children
数组,这很简单,除了我需要递归执行此操作,因为Page
包含Page
的数组。
MongoDB没有任何开箱即用的支持,它只支持2级深度人口。
这是我当前的查询(删除所有额外的内容以提高可读性),而不使用当前的.populate
方法(因为它无论如何都不会起作用):
Page.find(query)
.exec((err, pages) => {
if (err) {
return next(err);
}
res.json(pages);
});
我看了一下这个问题,这个问题很相似,但并不完全符合我的要求:
似乎使用父级递归填充,它也只从1个文档开始,而不是我使用文档数组的方案,因为我使用的是.find
而不是.findOne
例如。
如何为此创建自己的深度递归填充函数?
旁注:
我知道由于性能的原因,我不建议使用我需要的解决方案,但我得出的结论是唯一解决方案对我有用。无论是在前端还是后端,我都需要进行递归获取,并且在后端正确执行会大大简化操作。此外,页面数量不会大到足以导致性能问题。
答案 0 :(得分:0)
答案实际上是在前面问题的一个答案中撒谎,虽然有点模糊。这就是我最终得到的结果,效果非常好:
Page.find(query)
.or({label: new RegExp(config.query, 'i')})
.sort(config.sortBy)
.limit(config.limit)
.skip(config.offset)
.exec((err, pages) => {
if (err) {
return next(err);
}
// takes a collection and a document id and returns this document fully nested with its children
const populateChildren = (coll, id) => {
return coll.findOne({_id: id})
.then((page) => {
if (!page.children || !page.children.length) {
return page;
}
return Promise.all(page.children.map(childId => populateChildren(coll, childId)))
.then(children => Object.assign(page, {children}))
});
}
Promise.all(pages.map((page) => {
return populateChildren(Page, page._id);
})).then((pages) => {
res.json({
error: null,
data: pages,
total: total,
results: pages.length
});
});
});
函数本身应该重构为一个可以在任何地方使用的utils函数,它也应该更通用一些,所以它也可以用于其他深度种群。
我希望将来可以帮助其他人:)
答案 1 :(得分:0)
您可以递归填充字段,如:
opt.apply_gradients (final_grads)
请注意,对于第一次填充,您不需要指定User.findOne({ name: 'Joe' })
.populate({
path: 'blogPosts',
populate: {
path: 'comments',
model: 'comment',
populate: {
path: 'user',
model: 'user'
}
}
})
.then((user) => {});
属性,因为它已在您的model
架构中定义,但对于下一个嵌套群体,您需要执行此操作这一点。