Leveraging Mongodb's aggregate feature to calculate the overall quantity of a specific product that has been ordered across all

Recently delving into the realm of javascript, I am currently tackling a dashboard project that requires displaying the total quantity of each product ordered. Although I have successfully defined a variable 'qty' to represent the quantity of an individual product, I am facing challenges in calculating the overall quantity of said product from all orders. Provided below is my current progress along with any pertinent documents for reference. Any assistance or advice offered on navigating this task would be greatly appreciated.

Extract from orderRouter.js

  const qty = await Order.aggregate([
      {
        $group: {
          _id: '$name',
          count: { $sum:'$qty'},
        },
      },
    ]);

orderRouter.js

import express from 'express';
import expressAsyncHandler from 'express-async-handler';
import Order from '../models/orderModel.js';
import User from '../models/userModel.js';
import Product from '../models/productModel.js';
import {isAdmin, isAuth, isSellerOrAdmin} from '../utils.js';

const orderRouter = express.Router();
orderRouter.get(
  '/',
  isAuth,
  isSellerOrAdmin,
  expressAsyncHandler(async (req, res) => {
    const seller = req.query.seller || '';
    const sellerFilter = seller ? { seller } : {};
    const orders = await Order.find({ ...sellerFilter }).populate(
      'user',
      'name',
    );
    res.send(orders);
  })
);



orderRouter.get(
  '/summary',
  isAuth,
  isAdmin,
  expressAsyncHandler(async (req, res) => {
    const orders = await Order.aggregate([
      {
        $group: {
          _id: '$name',
          count: { $sum:'$qty'},
        },
      },
    ]);
    res.send({ qty  });
  })
);

orderRouter.get(
  '/mine',
  isAuth,
  expressAsyncHandler(async (req, res) => {
    const orders = await Order.find({ user: req.user._id });
    res.send(orders);
  })
);
orderRouter.post(
  '/',
  isAuth,
  expressAsyncHandler(async (req, res) => {
    if (req.body.orderItems.length === 0) {
      res.status(400).send({ message: 'Cart is empty' });
    } else {
      const order = new Order({
        seller: req.body.orderItems[0].seller,
        orderItems: req.body.orderItems,
        shippingAddress: req.body.shippingAddress,
        paymentMethod: req.body.paymentMethod,
        itemsPrice: req.body.itemsPrice,
        shippingPrice: req.body.shippingPrice,
        taxPrice: req.body.taxPrice,
        totalPrice: req.body.totalPrice,
        user: req.user._id,
      });
      const createdOrder = await order.save();
      res
        .status(201)
        .send({ message: 'New Order Created', order: createdOrder });
    }
  })
);
orderRouter.get(
  '/:id',
  isAuth,
  expressAsyncHandler(async (req, res) => {
    const order = await Order.findById(req.params.id);
    if (order) {
      res.send(order);
    } else {
      res.status(404).send({ message: 'Order Not Found' });
    }
  })
);

export default orderRouter;

orderModel.js

const orderSchema = new mongoose.Schema(
  {
    orderItems: [
      {
        name: { type: String, required: true },
        qty: { type: Number, required: true },
        image: { type: String, required: true },
        price: { type: Number, required: true },
        product: {
          type: mongoose.Schema.Types.ObjectId,
          ref: 'Product',
          required: true,
        },
      },
    ],
);
const Order = mongoose.model('Order', orderSchema);
export default Order;

Answer №1

Here are some useful collections:

collections = [
  {
    orderedItems: [
      {
        name: "product 1",
        qty: 20,
        image: "image1",
        price: 200,
        product: {
          type: "2222",
          ref: "Product",
          
        },
        
      },
      {
        name: "product 1",
        qty: 40,
        image: "image2",
        price: 300,
        product: {
          type: "333",
          ref: "Product",
          
        },
        
      },
      
    ]
  }
]

To separate the array of items, use $unwind

db.collection.aggregate([
  {
    $unwind: "$orderedItems"
  },
  {
    $group: {
      _id: "$orderedItems.name",
      count: {
        $sum: "$orderedItems.qty"
      },
      
    },
    
  },
  
])

The output will be:

[
  {
    "_id": "product 1",
    "count": 60
  }
]

Try it out on the mongoplayground

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

Vue.js navigation guards, restrict access to all unauthorized routes, grant entry to specific routes upon successful authentication

I'm currently working on implementing a navigation guard in Vue.js with a specific logic: I want to restrict access to all routes that require authentication and redirect users to the login page if they are not authenticated. The only exception is the ...

Steps for constructing an object containing an array of nested objects

I've been working on this problem for some time now, and it's starting to feel like a messy situation that just won't come together. I'm trying to recreate an object with 5 properties and a nested array of objects, but so far, it's ...

What are the best methods for concealing a ng-repeat element with AngularJS?

.controller('CouponsCtrl', ['$scope', '$http', '$window', '$location', '$ionicPopup','$ionicLoading', function($scope, $http, $window, $location, $ionicPopup,$ionicLoading) { ...

Manual mocking in Jest is only effective for the initial function call

In my project, I have created a custom XHR wrapper in utils/xhr.js and I am using Jest manual mocking feature to mock it. However, I am running into an issue where only the first XHR call is being tracked: utils/xhr.js let xhr = { get: function(par ...

Preserve the variable alterations for future promises

I have implemented promises in my database access using elasticsearchjs, which utilizes Bluebird. Each ID in the list triggers a new query, and I need to identify the failing query by its ID. const idList = ['id1', 'id2', 'id3&apo ...

To ensure the smooth functioning of a React application running on a Docker container in Ubuntu 16.04, it is

I'm currently in the process of setting up a docker container for running a react app that sends a fetch request to another docker container containing a node server. The deployment is on Ubuntu 16.04, however, after building and deploying the contain ...

What could be causing issues with my Ajax and JavaScript functionality?

While developing a website to search through my python database, I encountered an issue. The non-JavaScript version was functioning flawlessly. However, when attempting to implement AJAX so that the page would not have to be refreshed each time, I faced ...

Enhancing presentation with a multitude of pictures

I am currently in the process of developing a slideshow feature that includes an extensive collection of images for users to navigate through using 'next' and 'previous' buttons. At the moment, each time a user clicks on the navigation ...

What is causing the javascript in my svg files not to function when embedded in an html document?

I have the following code for an SVG: <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="470px" height="260px" version="1.1" onload="addEvent ...

Issue with the DocPad plugin for Gulp

I'm encountering an issue while trying to utilize the gulp docpad plugin. When I run docpad run, the following error message is displayed: Error: spawn UNKNOWN at exports._errnoException (util.js:837:11) at ChildProcess.spawn (internal/child_process. ...

Explore a JSON array within another JSON array

Here is a JSON format that I have: { "Project [id=1, dateDebut=2017-01-13, dateFin=2017-01-18, description=qsd, sponsor=qsd ]" : [ {"id":1,"title":"qsd ","description":"qsdqsd","dateFin":"2017-01-26"}, {"id":2,"title":"sss ","descriptio ...

What is the best way to populate nested elements with jQuery?

I am trying to showcase the latest NEWS headlines on my website by populating them using Jquery. Despite writing the necessary code, I am facing an issue where nothing appears on the webpage. Below is the HTML code snippet: <div class="col-md-4"> ...

Launching a React project using the terminal - my step-by-step process

I'm attempting to initiate a new react-app utilizing the command npx create-react-app <app name> as shown below: npx create-react-app new-app However, after downloading, it seems to be stuck. It's not progressing at all. I've even rei ...

Steps for transforming a JSON into a Class to generate objects

My JSON data is displayed below: var nodeclienthash={ socket:null, init : function() { // Initializing socket.io this.socket = new io.Socket(this.config.host, {port: this.config.port, rememberTransport: false}); } }; I am currently looking t ...

Retrieve the public URL from the index.html file following the build process

In my project, I utilized ReactJS by creating an app with the command npx create-react-app my-app. To build the project, I used yarn build. Within the package.json file, the scripts section appears as follows: "scripts": { "start": "react-scripts sta ...

I successfully merged two arrays (decks of cards) without using recursion, but I'm curious to understand where I went wrong with the recursive approach

Currently, I am working on a function that shuffles two arrays together using recursion. The goal is to combine the top and bottom halves of a deck of cards into a single array with elements interleaved. For example: The first element should come from the ...

Top method for passing props from child to parent React component

I am facing a challenge with passing data from child to parent components in React. I have an array that I need to save in my database, and I have set up a Parent component (AuthenticationPage.js) and a Child component (SignupForm.js) for this purpose. The ...

Creating a progress bar with a mouse listener in React Material Design

I encountered an issue while working with React and React Material-UI components. Here is what I'm trying to achieve: 1) When the user clicks a button in my component, I want to add a mousemove listener to the page and display a ProgressBar. 2) As ...

Ways to share code across AngularJS frontend and Node.js backend

How can code be effectively shared between an AngularJS client and a Node.js server? After creating an AngularJS application, I now need to develop a RESTful server to provide data to the client. Some Angular services used on the client-side could also be ...

Dynamic Selection of JSON Key-Value Pairs in React Framework

My json data structure resembles the following: { "index": 1, "ln": "27953", "name": "Product 1", "availability": { "day0726": "G", "day0727": "G", "day0728": "G", } } I am looking for a way to dynamically disp ...