#node.js #arrays #mongodb #express
#node.js #массивы #mongodb #выразить
Вопрос:
У меня есть эта коллекция:
{
"_id": "5f1bd6c7d90cb03e845adbbf",
"name": "John Doe",
"likes": [
{
"_id": "5f378b105d337347e8958a50",
"user": "5f357ac9c0d2019cc82b5a2f",
"post": "5f3032894cd4a000175d333c",
},
{
"_id": "5f354e351a98dd7c7081d72d",
"user": "5f357ac9c0d2019cc82b5a2f",
"post": "5f3bf7a44ed4f031bc575c2b"
},
{
"_id": "5f354cc2879f8a81b0ab28fe",
"user": "5f30380288a63e001755401e",
"post": "5f310ce5e18bad001792fb60"
}
]
Теперь я хочу найти все записи, которые соответствуют идентификаторам likes.post.
Это работает, но, очевидно, дает мне только одно сообщение:
const posts = await Post.find({ _id: [user.likes[0].post] });
res.json(posts);
Я попробовал цикл for, но он возвращает только одно сообщение. Когда я регистрирую это в консоли, я получаю все записи, которые соответствуют:
for (let i = 0; i < user.likes.length; i ) {
const posts = await Post.find({ _id: [user.likes[i].post] });
res.json(posts);
}
Ответ №1:
Вы можете сделать это с помощью $in
оператора.
const posts = await Post.find({ _id: { $in: user.likes.map(l => l.post) } });
res.json(posts);
Ответ №2:
Я попробовал цикл for, но он возвращает только одно сообщение. Когда я регистрирую это в консоли, я получаю все записи, которые соответствуют:
Построение цикла завершается с ошибкой, потому что вы отправляете ответ после первой итерации, и соединение закрывается. Вот как это исправить:
const posts = [];
for (let i = 0; i < user.likes.length; i ) {
const post = await Post.find({ _id: [user.likes[i].post] });
posts.push(post)
}
res.json(posts)
Или используйте карту, подобную этой:
const postPromises = user.likes.map(({ post }) => {
return Post.find({ _id: [user.likes[i].post] });
})
const posts = Promise.all(postPromises);
res.json(post)
Но тогда, вместо выполнения двух отдельных запросов, вы можете изменить любой запрос, который вы запускаете, чтобы получить этот документ.
Предполагая, что вы используете mongoose:
Author
.findOne({ name: 'John Doe' })
.populate({
path: 'likes',
populate: { path: 'post' }
})
;
Я в пути и не могу протестировать это сейчас, но если это не удастся, попробуйте это вместо:
Author
.findOne({ name: 'John Doe' })
.populate('likes.post')
;