Если я предполагаю, что схема сообщений похожа на эту
{
title: String,
content: String,
owner: { type: Schema.Types.ObjectId, ref: 'User'}
}
, тогда мы можем использовать агрегированный конвейер для получения сообщений друзей какого-то пользователя
что-то вроде этого
db.users.aggregate([
{
$match: {
_id: "userId1" // this should be of type ObjectId, you need to convert req.params.id to ObjectId (something like: mongoose.Types.ObjectId(req.params.id) instead of 'userId1')
}
},
{
$lookup: {
from: "posts",
let: {
friendsIDs: "$friends"
},
pipeline: [
{
$match: {
$expr: {
$in: ["$owner", "$$friendsIDs"]
}
}
}
],
as: "friendsPosts"
}
}
])
вы можете протестировать здесь Пн go Площадка
не стесняйтесь заменять эти 'userId1', 'userId2', ..., 'postId1,' postId2 ' , .. в этой ссылке с вашими реальными пользователями и идентификаторами сообщений
таким образом, вы получили сообщения друзей какого-то пользователя в одном запросе, а не в двух запросах
, тогда функция будет чем-то вот так
User.aggregate([
{
$match: {
_id: mongoose.Types.ObjectId(req.params.id)
}
},
{
$lookup: {
from: "posts", // this should be the posts collection name, It may be 'Post' not 'posts', check it
let: {
friendsIDs: "$friends"
},
pipeline: [
{
$match: {
$expr: {
$in: ["$owner", "$$friendsIDs"]
}
}
}
],
as: "friendsPosts"
}
}
]).then(result => {
// the aggregate pipeline is returning an array
// but we are sure it will be an array of only one element as we are searching for only one user, so we can use result[0]
result = result || []; // double check the result array
result[0] = result[0] || {}; // double check the user object
var posts = result[0].friendsPosts; // here is the friends posts array
// return the posts array
res.json(posts);
})
надеюсь, что это поможет
Обновление
Если нам нужно отсортировать firendsPosts, а затем ограничить их
мы можем используйте следующие
db.users.aggregate([
{
$match: {
_id: "userId1"
}
},
{
$lookup: {
from: "posts",
let: {
friendsIDs: "$friends"
},
pipeline: [
{
$match: {
$expr: {
$in: [
"$owner",
"$$friendsIDs"
]
}
}
}
],
as: "friendsPosts"
}
},
{
$unwind: "$friendsPosts" // unwind the array to get a stream of documents
},
{
$sort: {
"friendsPosts.createdAt": 1 // then sort the posts by the createdAt Date in ascending order
}
},
{
$group: { // then group the posts again after sorting
_id: "$_id",
friendsPosts: {
$push: "$friendsPosts"
}
}
},
{
$project: {
friendsPosts: {
$slice: ["$friendsPosts", 2] // this is to limit the posts
}
}
}
])
вы можете проверить это здесь Пн go Детская площадка 2