DEV Community

Cover image for NodeJS, ExpressJS, Redis, MongoDB - series #03
Functional Javascript
Functional Javascript

Posted on • Edited on

2

NodeJS, ExpressJS, Redis, MongoDB - series #03

Intro

These two code snippets have the identical behavior.
What does the code do?

See if it's intuitive enough to understand it just be reading it.
Read the "Notes" section below for the full explanation.

Snippet a.

app.post(apiEnum.api_findgroup_artistyearsformed, async (req, res) => {
  res.json(
    await mgArr_redis(dbEnum.nlpdb, collEnum.songsColl, "artistyearsformed"
      { $match: { formed: { $exists: true } } },
      { $group: { _id: "$formed", count: { $sum: 1 } } },
      { $project: { _id: 0, formed: "$_id", count: 1 } },
      sort({ count: -1, hw: 1 }),
    ));
});

Enter fullscreen mode Exit fullscreen mode

Snippet b.

app.post(apiEnum.api_findgroup_artistyearsformed, async (req, res) => {
  res.json(
    await mgArr_redis(dbEnum.nlpdb, collEnum.songsColl, "artistyearsformed",
      matchExists("formed"),
      groupCount("formed"),
      renameGroupKey("formed"),
      sortDescSecondaryAsc("count", "formed"),
    ));
});
Enter fullscreen mode Exit fullscreen mode

Notes

  • Code snippet A is the raw MongoDB database query syntax
  • Code snippet B is simply a wrapper func around each stage of the query pipeline.

  • The DB call returns this datashape. It gives a list of the count of bands formed in each year:

/*
  { count: 13, formed: '2001' },
  { count: 10, formed: '2000' },
  { count: 14, formed: '1999' },
  { count: 4, formed: '1998' },
*/
Enter fullscreen mode Exit fullscreen mode
  • The mongoDB query is wrapped in a Node.js ExpressJS route. Thus this query will return the data to those who are authorized to access the route:
app.post(apiEnum.api_findgroup_artistyearsformed, async (req, res) =>
Enter fullscreen mode Exit fullscreen mode
  • As an aside, only registered domains can successful access this route, by way of this configuration (but we'll talk more about secure routes later):
app.use(cors({ credentials: true, origin }));
Enter fullscreen mode Exit fullscreen mode
  • This resultset is very stable data, so it is a candidate for caching. I use a variant of mgArr, called mgArr_redis, which takes a third param as the cache key (in this case, "artistyearsformed") which uniquely identifies the resultset. The expiry time is configurable, and defaults to two hours. It takes a big load off your DB:
await mgArr_redis(dbEnum.nlpdb, collEnum.songsColl, "artistyearsformed",
Enter fullscreen mode Exit fullscreen mode
  • The MongoDB collection holding these musician/artist documents has a field named "formed" which holds the 4 digit year.

  • The matchExists("formed") is used to filter out artists who don't report their year formed

  • As you can see, doing a "group" (aka "group by") in mongo is easy as cake.

  • Notice the "Snippet b." is cleaner and more semantically rich in conveying what it does. You read it like the building blocks (stages) of a database query. The raw or wrapper syntaxes are interchangeable when using the "mgArr" utility func.

  • Doing secondary (or third or any number) sorts are a cinch in MongoDB.

What's Next?

  • Today we covered,
    ** Routes with ExpressJS
    ** Securing your ExpressJS route
    ** Caching with Redis
    ** Grouping data in MongoDB

  • If you have an questions, let me know

  • As the series goes on, we'll go deeper, solving some amazing real world problems in style. :)

AWS GenAI LIVE image

How is generative AI increasing efficiency?

Join AWS GenAI LIVE! to find out how gen AI is reshaping productivity, streamlining processes, and driving innovation.

Learn more

Top comments (0)

Tiger Data image

🐯 🚀 Timescale is now TigerData: Building the Modern PostgreSQL for the Analytical and Agentic Era

We’ve quietly evolved from a time-series database into the modern PostgreSQL for today’s and tomorrow’s computing, built for performance, scale, and the agentic future.

So we’re changing our name: from Timescale to TigerData. Not to change who we are, but to reflect who we’ve become. TigerData is bold, fast, and built to power the next era of software.

Read more

👋 Kindness is contagious

Explore this compelling article, highly praised by the collaborative DEV Community. All developers, whether just starting out or already experienced, are invited to share insights and grow our collective expertise.

A quick “thank you” can lift someone’s spirits—drop your kudos in the comments!

On DEV, sharing experiences sparks innovation and strengthens our connections. If this post resonated with you, a brief note of appreciation goes a long way.

Get Started