0

I have this collection:

{
        "_id": "5f1bd6c7d90cb03e845adbbf",
        "name": "John Doe",
        "likes": [
            {
                "_id": "5f378b105d337347e8958a50",
                "user": "5f357ac9c0d2019cc82b5a2f",
                "post": "5f3032894cd4a000175d333c",
            },
            {
                "_id": "5f354e351a98dd7c7081d72d",
                "user": "5f357ac9c0d2019cc82b5a2f",
                "post": "5f3bf7a44ed4f031bc575c2b"
            },
            {
                "_id": "5f354cc2879f8a81b0ab28fe",
                "user": "5f30380288a63e001755401e",
                "post": "5f310ce5e18bad001792fb60"
            }
        ]

Now I want to find all posts that match the IDs of likes.post.

This works but obviously only gives me one post:

const posts = await Post.find({ _id: [user.likes[0].post] });
res.json(posts);

I tried a for-loop but it only gives back one post. When I console log this I get all posts that match:

for (let i = 0; i < user.likes.length; i++) {
  const posts = await Post.find({ _id: [user.likes[i].post] });
  res.json(posts);
}

2 Answers 2

1

You can do that by using $in operator.

const posts = await Post.find({ _id: { $in: user.likes.map(l => l.post) } });
res.json(posts);

Document

Sign up to request clarification or add additional context in comments.

Comments

0

I tried a for-loop but it only gives back one post. When I console log this I get all posts that match:

The loop construct fails because you're dispatching a response after the first iteration and the connection is closed. Here's how to fix that:

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)

Or use a map like so:

const postPromises = user.likes.map(({ post }) => {
  return Post.find({ _id: [user.likes[i].post] });
})

const posts = Promise.all(postPromises);
res.json(post)

But then, instead of running two separate queries, you can modify whatever query you run to obtain that document. Assuming you are using mongoose:

Author
  .findOne({ name: 'John Doe' })
  .populate({
    path: 'likes',
    populate: { path: 'post' }
  })
;

I'm on the move and can't test this now, but if that fails, try this instead:

Author
  .findOne({ name: 'John Doe' })
  .populate('likes.post')
;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.