因此,这是一个常见的问题,获取带有评论的帖子,我似乎在MongoDB中无法解决,这与在MySQL中使用left-join
可以轻松解决的问题不同。
我想获取MongoDB中每条帖子的最新8条帖子,并带有 2条最近评论。
我不想重组帖子数据以包含匹配的评论ID的列表,因为我希望将来会有成千上万的评论。
我真的不想求助于帖子,然后使用帖子ID执行8个单独的查询以找到2条最新评论。 (尽管我猜是次佳的解决方案)
我尝试设置postSchema.virtual('comments', ..)
,然后在执行查询时使用Post.find(..).populate('comments', options: {limit: 2})
进行填充,但是不幸的是,限制返回了inconsistent results。
Post:
{ body: "post1" }
{ body: "post2" }
{ body: "post3" }
...
{ body: "post8" }
Comment:
{ post_id: 1, message: "comment1" }
{ post_id: 2, message: "comment2" }
{ post_id: 2, message: "comment3" }
{ post_id: 3, message: "comment4" }
所有文档都有一个date
字段,但是为了简洁起见将其删除
{
body:"post1",
comments: [
{ post_id: 1, message: "comment1" }
]
}
{
body:"post2",
comments: [
{ post_id: 2, message: "comment2" },
{ post_id: 2, message: "comment3" }
]
}
{
body:"post3",
comments: [
{ post_id: 3, message: "comment4" }
]
}
...
答案 0 :(得分:2)
如果您使用的是MongoDB 3.6或更高版本,则可以使用$lookup with custom pipeline将带有评论的帖子“加入”并接受2个最新的帖子(使用$limit)
let items = [{ // overview
title: 'Overview',
path: `/root/overview`,
module: "overview/menu",
icon: "fa fa-home"
}, // overview
{ // cardboards
title: 'Cardboards',
path: `/root/cardboards`,
module: "cardboards/menu",
icon: "fa fa-files-o",
subs: [{
title: 'Suppliers',
path: `/root/cardboards/suppliers`,
module: "suppliers/menu",
icon: "fa fa-handshake-o"
},
{
title: 'Employees',
path: `/root/cardboards/employees`,
module: "employees/menu",
icon: "fa fa-address-book-o"
},
]
}, // cardboards
{ // charts
title: 'Charts',
path: `/root/charts`,
icon: "fa fa-area-chart",
module: "charts/menu",
subs: [{
title: 'Activity',
path: `/root/charts/activity`,
module: "charts/activity/menu"
}, ]
}, // charts
{ // settings
title: 'Settings',
path: `/root/settings`,
module: "settings/menu",
icon: "fa fa-cogs",
subs: [{
title: 'Permissions',
path: `/root/settings/permissions`,
module: "settings/permissions/menu",
icon: "fa fa-file-text-o"
}]
} // settings
];
function flatten(tree) {
let res = [];
function traverse(arr) {
res.push(...arr);
arr.forEach(o => traverse(o.subs || []));
}
traverse(tree);
return res;
}
let pathIndex = flatten(items).reduce((acc, curr) => {
if (curr.path) acc[curr.path] = curr;
return acc;
}, {});
let breadcrumbs = ["/", "/root", "/root/cardboards", "/root/cardboards/employees", "/root/cardboards/employees/123"];
console.log(breadcrumbs.filter(path => path in pathIndex)
.map(path => ({title: pathIndex[path].title, path})));