Hi Meteor folks,
We have spotted some bottlenecks in our production app regarding the check for an existing document in a collection.
currently we have a simple helper function like the following:
export const isExistingUserId = async (id: string): Promise<boolean> => {
return (await Meteor.users.find(id, { limit: 1 }).countAsync()) > 0;
};
This does not seem to be well written (code base goes back to 6 years…) and furthermore, deprecated
Thanks to Monti APM we have seen, that these kind of checks take up a big chunk of “response time”.
What would be the smarter way to implement such checks?
Alternative with findOneAsync?
export const isExistingUserId = async (id: string): Promise<boolean> => Boolean(await Meteor.users.findOneAsync(id, { fields: { _id: 1 } }));
Alternative to the deprecated CountAsync?
Some insights / best practices are kindly welcome.
We are checking the existence of a document in this way for now…
export const isExistingUserId = async (userId: string): Promise<boolean> => {
return typeof userId === 'string' && Boolean(await Meteor.users.countDocuments({ _id: userId }));
};
denyhs
May 27, 2024, 12:39pm
3
About the countAsync, if you’re using Meteor 3, we’re using countDocuments
under the hood . So no deprecated methods is being called.
Did you check the response time for this? Is it better?
What about trying findOneAsync
?
export const isExistingUserId = async (userId: string): Promise<boolean> => {
return typeof userId === 'string' && !!(await Meteor.users.findOneAsync(userId, { fields: { _id: 1 } }));
};
This should be fast if you have the _id
indexed (it should be by default). And I believe it should be faster than countDocuments
, but you could test and share it with us the results
We are still on Meteor v2.14 … but refactored a lot of code to be able to upgrade to v3 (still a few packages that are blocking us from upgrading)
The findOneAsync
version was way slower than the currently used countDocuments
implementation.
findOneAsync - 1676ms
countAsync - 1300ms
countDocuments - 36ms
One important remark for the current implementation:
we are now using this.unblock()
whenever appropriate
we switched from using Collection.find...
to Collection.rawCollection().find...
in our server methods
Overall performance has been increased, but still some bottlenecks (probably CPU / Server ressources)