What is the most efficient way to determine the monthly user count using a MongoDB query that takes into account the previous count?

I am looking to calculate the total count of users based on the previous month's count data.

Here is an example of how the results array should be structured:

RESULTS  [
  { count: 1, accumulatedCount: 1, month: 12, year: 2021, verified: true },
  { count: 3, accumulatedCount: 4, month: 1, year: 2022, verified: true },
  { count: 3, accumulatedCount: 7, month: 2, year: 2022, verified: true },
  { count: 1, accumulatedCount: 8, month: 3, year: 2022, verified: true },
]

Currently, my aggregation pipeline is structured as follows:

const results = await this.accountModel.aggregate([
      {
        $match: {
          ...match,
          createdAt: {
            // $gte: range.from,
            $lte: range.to,
          },
        },
      },
      { $unwind: '$organizations' },
      {
        $group: {
          _id: {
            month: { $month: '$createdAt' },
            year: { $year: '$createdAt' },
            verified: '$organizations.verified',
          },
          count: { $sum: 1 },
        },
      },
      {
        $project: {
          _id: 0,
          month: '$_id.month',
          year: '$_id.year',
          count: 1,
          verified: '$_id.verified',
        },
      },
    ]);

The current output of the aggregation pipeline includes the following:

RESULTS  [
  { count: 1, month: 10, year: 2022, verified: true },
  { count: 4, month: 7, year: 2022, verified: true },
  { count: 3, month: 2, year: 2022, verified: true },
  { count: 1, month: 3, year: 2022, verified: true },
  { count: 1, month: 12, year: 2021, verified: true },
  { count: 2, month: 1, year: 2022, verified: true },
  { count: 1, month: 8, year: 2022, verified: true }
]

Essentially, I need to utilize a reduce function to aggregate the count values based on previous and current data.

I have not found appropriate options for this in the MongoDB documentation.

The version of "mongodb" package I am using is "3.6.3".

Answer №1

Here is a method to achieve the desired outcome:

db.collection.aggregate([
  {
    "$group": {
      "_id": null,
      "docs": {
        "$push": "$$ROOT"
      }
    }
  },
  {
    "$project": {
      docs: {
        "$reduce": {
          "input": "$docs",
          "initialValue": {
            accumulatedCount: 0,
            data: []
          },
          "in": {
            accumulatedCount: {
              "$sum": [
                "$$this.count",
                "$$value.accumulatedCount"
              ]
            },
            data: {
              "$concatArrays": [
                "$$value.data",
                [
                  {
                    "$mergeObjects": [
                      "$$this",
                      {
                        accumulatedCount: {
                          "$sum": [
                            "$$this.count",
                            "$$value.accumulatedCount"
                          ]
                        }
                      }
                    ]
                  }
                ]
              ]
            }
          }
        }
      }
    }
  },
  {
    "$unwind": "$docs.data"
  },
  {
    "$replaceRoot": {
      "newRoot": "$docs.data"
    }
  }
])

To summarize, group all documents into an array and iterate over them using $reduce, maintaining a count total and updated document list with accumulatedCount. Lastly, flatten the list and set the documents as the root.

Interactive demonstration here.

You can seamlessly integrate these new stages into your pipeline for execution.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Deleting a page reference from the page history stack in Angular 4

I am working on my angular web application and I am looking for a way to remove a specific page reference from the angular page history stack. For example, if I navigate from the login page to the dashboard page, I want to remove the login page reference f ...

Odd behaviour when using JSON in CouchDB

I have developed an updates handler in CouchDB with test code like this (before inserting into Couch I am removing newlines): function (doc, req) { if (req['userCtx']['roles'].indexOf('editor') < 0) { return [ ...

Toggle between different socket.io servers for seamless connectivity

I'm looking for help with a situation where I need a socket.io client to connect to server A, disconnect, and then connect to server B. Any ideas on how I can achieve this? Thanks in advance! UPDATE: Attached below is the code snippet that's gi ...

Guide to sending multiple forms from an HTML page to another PHP page

What is the best way to submit multiple forms on a single HTML page to a PHP page and process all the form elements in PHP upon clicking one button? Any suggestions are appreciated. Thank you in advance. <form id="form1" name="form1"action="abc.php" ...

Is it seriously impossible to create a TTL index on a field that is already indexed?

According to the 10Gen Docs, it states: "You cannot create a TTL index on a field that already has an index." However, in practice, this seems to work without any issues. What is the actual meaning behind this statement from the documentation? In the ...

Steps for creating a table with a filter similar to the one shown in the image below

https://i.sstatic.net/zR2UU.png I am unsure how to create two sub-blocks within the Business A Chaud column and Potential Business Column. Thank you! I managed to create a table with input, but I'm struggling to replicate the PUSH & CtoC Column for ...

Attempts to access the URL but receives no feedback

While using casperjs, I encountered an issue with scraping a particular link - . It seems like I am not receiving any response from this link. No matter what I try, it always stops at this point in the cycle. I have isolated the problem, but I just can&apo ...

Why is my snapshot returning null, even though there are values in the Firebase Database?

I am currently facing an issue in my code related to the snapshot. Specifically, I am trying to retrieve the value of quantity from my Firebase Database. Here's a snapshot of my database: https://i.sstatic.net/qN6m4.jpg and https://i.sstatic.net/Gw ...

Operating on Javascript Objects with Randomized Keys

Once I retrieve my data from firebase, the result is an object containing multiple child objects. myObj = { "J251525" : { "email" : "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6c3823212 ...

State of loading getServerSideProps in Next.js

Can we implement a loading state similar to when retrieving data on the client-side? I'm interested in having a loading state, maybe with a loading-skeleton like react-loading-skeleton On the client-side, we can achieve this by: import useSWR from & ...

Discover the ultimate solution to disable JSHint error in the amazing Webstorm

I am encountering an error with my test files. The error message states: I see an expression instead of an assignment or function call. This error is being generated by the Chai library asserts. Is there a way to disable this warning in Webstorm? It high ...

Guide on including a particular field in an array of objects within a MongoDB projection

I have a question regarding a complex query that involves joining 3 tables and projecting data. The query is as follows: db.incomedistros.aggregate([ { $lookup: { from: "orders", localField: "orderId", ...

Changing the background color of the dropdown button in Vue Bootstrap: A step-by-step guide

I've been struggling to modify the background color of a dropdown button, but no method seems to work. I've attempted changing it by using ID, removing its class and applying a new one, and even using !important to override the styles, but the ba ...

What's the best way to animate the navigation on top of an image for movement?

I am currently in the process of creating my website as a graphic designer. My unique touch is having the navigation positioned on top of an image (which is animated via flash). This setup is featured prominently on my homepage, which is designed with mini ...

Incorporate additional text to the downloads hyperlink using jquery

Is it possible to achieve this using jQuery since I am unable to directly modify the HTML markup? I am looking to append download.php?file= to a URL without replacing the entire href attribute. Here's an example of what I'm trying to achieve: & ...

Ways to disable the ability to close a bootstrap modal by pressing the backspace key

How can I enable the backspace button in a Bootstrap Modal form for textboxes and textareas? $('body').keydown(function (e) { if ($('#myModal').is(':visible')) { if (e.keyCode == 8) { retu ...

Issues with Bootstrap Table Column Widths not Adjusting Properly

I am facing an issue with my Bootstrap 4 table where the fixed column widths specified in the header row are not being respected when the table is rendered. The Time column, for example, should only be 5% of the width but it is taking up more space than ex ...

Can a Node.js dependent library be integrated into Cordova?

After setting up an android project using Cordova, I came across a javascript library that relies on node.js to function. Since Cordova operates with node.js, can the library be invoked within the Cordova environment? ...

Is there a way to successfully integrate a JavaScript file that has been downloaded from `npm` or `yarn` into a web client or

Currently, I am following a guide titled "Headless Drupal with React" on Medium. The tutorial itself does not address my specific questions. In the tutorial, it demonstrates importing React and ReactDOM directly from CDN in the .html file. My query revolv ...

When attempting to parse a JSON feed with jQuery and innerHTML, the data fails to display

Having trouble parsing a JSON feed using jQuery and innerHTML, but for some reason it's not working as expected. No errors are being displayed in the console and the feed itself is functioning properly. Not quite sure why this issue is occurring. < ...