pradumn bansal
pradumn bansal

Reputation: 131

Mongoosejs: Is findById faster than findOne?

I am working on a project where a user can have several posts.

So I want to know which approach is better for querying all his posts

  1. having a posts field in user model which contains all the posts ids, and then searching for each through FindById in posts collection which contains all the posts from all the users

  2. to query all the posts collection at once and find all the posts from given user

Upvotes: 0

Views: 2024

Answers (1)

sammoore
sammoore

Reputation: 330

I'll try to answer both the question in the title as well as your specific use case, starting with the title.

  • Outside the context of your use case, findOne is likely insignificantly faster when provided valid ObjectIds, in the sense that passing an invalid ID through .findOne({ _id }) will not ensure _id is a valid ObjectId.

  • However, given malformed ID's, .findById(_id) will prevent a query from executing whatsoever and actually throw a CastError, which would be more performant if you are unsure of the origin of the ID, e.g. user input, and have the added benefit if you'd like to provide an error message rather than an empty result.

As previously mentioned, these details seem irrelevant for your use case, since the ObjectId's in question are already stored in the database, not to mention this appears to be a question of what queries in what order would be theoretically faster, not one query helper over the other.

  • If you already have the ObjectId of the user in question, you save time by removing the need to query the User collection altogether by querying the Posts table directly. This is assuming you have an index on the field containing the User's ID. As you suggested:

Posts.find({ userId })

  • If you don't already know the user's ID, it would be keen to use the document population technique, since this matches your use case and has likely been optimized for this purpose. One (untested) example given a Post and User model could be:

User .findOne({ foo: 'bar' }) .populate('posts') .select('-id posts')

This should return an object with a single key posts containing an Array of the posts.

Upvotes: 1

Related Questions