Retrieve documents from MongoDB that were created within the last week and return a count of 0 for any days in which no documents were created

I need to extract documents from the last 7 days stored in my Mongo Database.

I have successfully retrieved data in the desired format, where specific dates and the number of tickets created on those dates are returned:

{
    "datesUsed": {
        "startDate": "2022-04-02T14:42:14.223Z",
        "endDate": "2022-04-09T14:42:14.223Z"
    },
    "data": [
        {
            "date": "02/04/2022",
            "numOfTickets": 1
        },
        {
            "date": "03/04/2022",
            "numOfTickets": 1
        },
        {
            "date": "04/04/2022",
            "numOfTickets": 2
        },
        {
            "date": "06/04/2022",
            "numOfTickets": 1
        },
        {
            "date": "07/04/2022",
            "numOfTickets": 1
        },
        {
            "date": "08/04/2022",
            "numOfTickets": 2
        },
        { 
            "date": "09/04/2022",
            "numOfTickets": 1
        }
    ]
}

The issue arises when Mongo only returns data for days with documents created, leaving out days like 05/04/2022 when no document was created.

My goal is to include another JSON object that accounts for these missing days as well:

{
            "date": "05/04/2022",
            "numOfTickets": 0
}

This is what I currently have implemented:

const companyId = req.query.companyId;
    let dates = [];
    const data = [];
    // Last 7 days
    const endDate = new Date();
    const startDate = new Date(Date.now() - 604800000);

    // Retrieve tickets from the past 7 days
    const allCompanyTickets = await ticketModel
      .find({
        company_id: companyId,
        createdAt: { $gte: new Date(startDate), $lte: new Date(endDate) },
      })
      .sort({ createdAt: 1 });

      console.log(allCompanyTickets)

    // Add them to an array
    allCompanyTickets.forEach((ticket) => {
      dates.push(ticket.createdAt.toLocaleDateString());
    });

    // Calculate occurrences of days in the dates array
    function countOccurrences(arr) {
      return arr.reduce(function (a, b) {
        a[b] = a[b] + 1 || 1;
        return a;
      }, []);
    }

    // Construct an object based on the calculated data
    const datesOrdered = countOccurrences(dates);

    // Assign keys to the data and push it to a new array
    for (let key in datesOrdered) {
      const tempObj = { date: key, numOfTickets: datesOrdered[key] };
      data.push(tempObj);
    }

    res.status(200).json({ datesUsed: { startDate, endDate }, data: data });

Answer №1

Here is an example:

db.ticketModel.aggregate([
  {
    $set: {
      unusedDates: {
        $range: [0, { $dateDiff: { start: "$start", end: "$end", unit: "day" } }]
      }
    }
  },
  {
    $set: {
      unusedDates: {
        $map: {
          input: "$unusedDates",
          in: {
            date: {
              $dateAdd: {
                start: { $dateTrunc: { dt: "$used.startDt", unit: "day" }},
                unit: "day",
                amount: "$$this"
              }
            },
            ticketCount: 0
          }
        }
      }
    }
  },
  {
    $set: {
      data: {
        $filter: {
          input: "$unusedDates",
          condition: { $not: { $in: ["$$this.date", "$data.date"] }}
        }
      }
    }
  }
])

Check it out on Mongo Playground

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

Is there a way to programmatically toggle a button's enabled state depending on the content of a text input field?

I want to create a functionality where a button will be enabled if the value in a textbox is 'mypassword'. If it's not equal to 'mypassword', then the button should be disabled. I've attempted the code below, but it doesn&apos ...

Tips for efficiently resolving and compiling a bug within an NPM package, ensuring it is accessible to the build server

This question may seem a bit unconventional. I am currently using an npm package that includes built-in type definitions for TypeScript. However, I have discovered a bug in these definitions that I am able to easily fix. My goal is to make this updated ve ...

Ways to display a price near a whole number without using decimal points

Currently, I am working on an ecommerce project where the regular price of an item is $549. With a discount of 12.96% applied, the sale price comes down to $477.8496. However, I want the sale price to be displayed as either $477 or $478 for simplicity. Yo ...

Pattern for either one or two digits with an optional decimal point in regular expressions

Currently, I'm utilizing for input masking. I am specifically focusing on the "patterns" option and encountering difficulties while trying to create a regex expression for capturing 1 or 2 digits with an optional decimal place. Acceptable inputs: ...

Utilizing ajax for fetching a data table

I am new to using ajax and have successfully retrieved data from a table. However, I am now trying to pull in an entire data grid but not sure how to achieve this. In my index.php file, I have the following code: <html> <head><title>Aj ...

Transform the display format of the input type date field from 'MM/DD/YYYY' to 'February 5, 2012' in a React.js application using Material-UI's TextField component

https://i.stack.imgur.com/9p7Mz.jpg I am working with a material-ui/ TextField date component and I am looking to maintain the current style and input method, but I need to adjust how the entered value is displayed to the 'en-us' format. const o ...

JQuery addClass function not functioning properly when used in conjunction with an AJAX request

I have a website where I've implemented an AJAX pagination system. Additionally, I've included a JQUERY call to add a class to certain list items within my document ready function. $(document).ready(function(){ $(".products ul li:nth-child(3 ...

Leveraging the Railway Pathway from the Google Maps API

I need to customize my map to display only railway stations instead of the entire map. How can I achieve this? Below is the code I have attempted: <html> <head> <style type="text/css"> html { height: 100% } ...

Angular Pagination: Present a collection of pages formatted to the size of A4 paper

Currently, I am working on implementing pagination using NgbdPaginationBasic in my app.module.ts file. import { NgbdPaginationBasic } from './pagination-basic'; My goal is to create a series of A4 size pages with a visible Header and Footer onl ...

Duo and reference loop

I'm trying to learn how to use backreferences in JavaScript. I have an array and want to replace it within a string. Here's what I've attempted so far: var items = ["book", "table"]; var sentence = "The $1 is on the $2"; var newSentence ...

Is there a way to extract data from a JSON file with dc.js?

As a beginner in programming, I am looking to learn how to import data from a JSON file using dc.js. ...

Determine the availability of a distant website through AJAX requests

My website runs PHP's cURL to check the online status of 5 different URLs, however, this process tends to slow down the page load time significantly, especially if one of the sites being checked is not working. Someone suggested using jQuery's a ...

Issue encountered in TypeScript: Property 'counter' is not found in the specified type '{}'.ts

Hey there, I'm currently facing an issue while trying to convert a working JavaScript example to TypeScript (tsx). The error message I keep encountering is: Property 'counter' does not exist on type '{}'.ts at several locations wh ...

Having trouble with JSONP cross-domain AJAX requests?

Despite reviewing numerous cross-domain ajax questions, I am still struggling to pinpoint the issue with my JSONP request. My goal is simple - to retrieve the contents of an external page cross domain using JSONP. However, Firefox continues to display the ...

Improving efficiency of basic image carousel in Angular 8

In my Angular 8 app, I am developing a basic carousel without relying on external libraries like jQuery or NgB. Instead, I opted to use pure JS for the task. However, the code seems quite cumbersome and I believe there must be a more efficient way to achie ...

Integrating a fresh element into the carousel structure will automatically generate a new row within Angular

I'm currently working on an Angular4 application that features a carousel displaying products, their names, and prices. At the moment, there are 6 products organized into two rows of 3 each. The carousel includes buttons to navigate left or right to d ...

Encountering an Uncaught Error: MyModule type lacks the 'ɵmod' property

I am currently working on developing a custom module to store all my UI components. It is essential that this module is compatible with Angular 10 and above. Here is the package.json file for my library: { "name": "myLibModule", &qu ...

Scanning barcode and Qrcode with Angular js HTML5 for seamless integration

Looking to scan Barcode and Qrcode on Android, iPhone, and iPad devices for a project that is built on AngularJS and HTML5 as a mobile website. The requirement is not to download any third-party native application on the device, ruling out the use of nati ...

Accurate representation of a JavaScript object using Node.js Express

I have a certain structure that I need to display on my JADE page, so I created a JSON-like object to store the data. This is how the JSON object looks like : var dataSet1 = { meta: { "name": "Some text", "minimum": mini_2, "ma ...

If the number exceeds 1, then proceed with this action

I currently have a variable called countTicked, which holds an integer representing the number of relatedBoxes present on the page. I am in need of an if statement that will perform certain actions when the value stored in countTicked exceeds 1. if (!$(c ...