1
\$\begingroup\$

I'm making one call to a mongoDB database to fetch a list of existing collections and then looping through the collection list and fetching their document count.

All db methods are promises and i'm getting them to fully resolve before responding to an API req. Here's my code

let records = {}
let promises = []

nosqldb.get().listCollections().toArray()
  .then(function(collections) {
    collections.map((coll) => {
      var collectionName = coll.name;
      var collection = nosqldb.get().collection(collectionName);
      promises.push(collection.count().then((count) => {
        records[collectionName] = count;
      }));
    });
    return Promise.all(promises);
  })
  .then(function() {
    return res.status(200).json(records);
  })
  .catch(function(err) {
    return res.status(500).send(err);
  });

As you can see , i'm looping through all collection names and asking the db to return their document count. I push these promises to an Promise array and having all of them resolve before sending the response.

Is this approach correct or is there a more elegant way?

Thanks

\$\endgroup\$
1
\$\begingroup\$

forEach vs map

When using map function, we're supposed to return something back from the function parameter. In the code above you do map and populate the promises collection by pushing to it. If you want to have the external collection as it is now, a forEach should be more readable than a map.

With map, the function may look like this. Also, notice that this allows joining the declaration and the assignment of promises array within the body of then(...):


let records = {}
nosqldb.get().listCollections().toArray()
  .then(collectionList => {
    const promises = collectionList.map(collection =>
      nosqldb.get().collection(collection.name).count().then(count => { records[collection.name] = count; })
    );
    return Promise.all(promises);
  })
  .then(() => res.status(200).json(records))
  .catch((err) => res.status(500).send(err));

Side note

You may want to limit the number of collections in which you do .count(). If you have dozens or hundreds or even more collections, you this function may attempt to open as many connections (IDK the details). Also, the function execution time will be really long.

A typical solution in limiting is pagination and/or filtration of the things being counted.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.