Leos Literak
Leos Literak

Reputation: 9406

Fetching multiple queries from Mongo

Is there a better / more optimal way how to fetch multiple queries from Mongo in NodeJS? I run this code in a loop for every user so I worry of performance and reliability of this code when my user base grows.

const cron = require('node-cron');
cron.schedule(process.env.SCHEDULE_TIME, async () => calculateUserHonors(), {
  scheduled: true,
  timezone: 'Europe/Prague',
});

const calculateUserHonors = async () => {
 // for loop for every user in database
let pollVotesCount, commentVotesCount, sharesCount, commentsCount, blogCount;
const pollVotesPromise = getPollVoteCount(dbClient, userId);
const commentVotesPromise = getCommentVotesCount(dbClient, userId);
const sharesPromise = getShareLinkCount(dbClient, userId);
const commentsPromise = getCommentedCount(dbClient, userId);
const blogPromise = getBlogCount(dbClient, userId);
Promise.all([pollVotesPromise, commentVotesPromise, sharesPromise, commentsPromise, blogPromise]).then((values) => {
  pollVotesCount = values[0];
  commentVotesCount = values[1];
  sharesCount = values[2];
  commentsCount = values[3];
  blogCount = values[4];
});

const getPollVoteCount = async (dbClient, userId) => dbClient.db().collection('poll_votes').find({ user: userId }).count();

const getCommentVotesCount = async (dbClient, userId) => dbClient.db().collection('comment_votes').find({ 'user.id': userId }).count();

const getShareLinkCount = async (dbClient, userId) => dbClient.db().collection('link_shares').find({ user: userId }).count();

const getCommentedCount = async (dbClient, userId) => dbClient.db().collection('comments').find({ 'user.id': userId }).count();

const getBlogCount = async (dbClient, userId) => dbClient.db().collection('items').find({ 'info.author.id': userId }).count();

Upvotes: 0

Views: 117

Answers (1)

domenikk
domenikk

Reputation: 1743

You should look into aggregation pipelines: https://docs.mongodb.com/manual/reference/operator/aggregation-pipeline/

For example, to get the poll_votes:

dbClient.db().collection('poll_votes').aggregate([
    { $group: { _id: '$user', count: { $sum: 1 } } },
    { $addFields: { user: '$_id', pollVotes: '$count' } }
]);

You would get an array with poll votes for each user.

Upvotes: 1

Related Questions