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. :)

MongoDB Atlas runs apps anywhere. Try it now.

MongoDB Atlas runs apps anywhere. Try it now.

MongoDB Atlas lets you build and run modern apps anywhere—across AWS, Azure, and Google Cloud. With availability in 115+ regions, deploy near users, meet compliance, and scale confidently worldwide.

Start Free

Top comments (0)

Feature flag article image

Create a feature flag in your IDE in 5 minutes with LaunchDarkly’s MCP server ⏰

How to create, evaluate, and modify flags from within your IDE or AI client using natural language with LaunchDarkly's new MCP server. Follow along with this tutorial for step by step instructions.

Read full post

👋 Kindness is contagious

Discover fresh viewpoints in this insightful post, supported by our vibrant DEV Community. Every developer’s experience matters—add your thoughts and help us grow together.

A simple “thank you” can uplift the author and spark new discussions—leave yours below!

On DEV, knowledge-sharing connects us and drives innovation. Found this useful? A quick note of appreciation makes a real impact.

Okay