Calculating the average value of an attribute in an array using Mongodb (Mongoose)

Seeking assistance with a query to find sellers near users based on location input and sorting them by average rating. Is this achievable? Snippet of the model including an array of reviews:

    const sellerSchema = new mongoose.Schema({
        _id: Mongoose....ObjectId
            //... 
        reviews: [
        {
          by: {
            type: mongoose.Schema.Types.ObjectId,
            ref: "User",
          },
          title: {
            type: String,
          },
          message: {
            type: String,
          },
          rating: Number,
          imagesUri: [{ String }],
          timestamp: {
            type: Date,
            default: Date.now,
          },
        },
      ],
    });

Aggregate function used as follows:

const seller = await Seller.aggregate(
    [
      {
        $geoNear: {
          near: {
            type: "Point",
            coordinates: [longitude, latitude],
          },
          distanceField: "distance",
          spherical: true,
          maxDistance: radius,
        },
      },
      rating_minimum ? { $match: { rating: { $gt: rating_minimum } } } 
       : {},
      {$limit: limit},
    ]);

Consideration for using $group to calculate avgReview and then sort by reviews:

{$group:{averageReviews: { $avg: "$reviews.rating"}},
{$sort: { averageReviews: 1 } },
{$limit: limit}

Answer №1

If you have an array of reviews per document and want to calculate the average rating, consider using $reduce instead of $group:

 {
    $addFields: {
      ratingSum: {
        $reduce: {
          initialValue: 0,
          input: "$reviews",
          in: {$sum: ["$$value", "$$this.rating"]}
        }
      }
    }
  },
  {
    $addFields: {
      "averageReviews": {"$divide": ["$ratingSum", {$size: "$reviews"}]
      }
    }
  },
  {$sort: { averageReviews: 1 } },
  {$limit: limit}

You can check out this example on the playground.

If you are aiming to limit the final results to 3 sellers, then you are doing it correctly.

Also, make sure your seller schema includes the location of the seller for use with $geoNear.

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

Tips on removing properties from an object recursively according to their key/value pairs

My current task involves removing specific children of an object based on whether their "size" key is set to 0. To achieve this, I am utilizing the npm package directory-tree to generate a JavaScript object representation of a chosen directory. The stru ...

Is it possible to create an API directly within the URL of a React.js application, similar to how Next.js allows?

When using Next.js, I can access my application on localhost:3000, and also access my API from localhost:3000/api/hello. I'm curious if there is a way to achieve this same setup with React.js and another framework like Express.js? If Next.js is not ...

Exploring the functionality of className using materialUI

Attempting to test whether my component has a specific class is proving challenging. This difficulty stems from the fact that the class is generated using MaterialUI. For instance, I am looking for a class named spinningIconCenter, but in reality, it appea ...

Is it possible to view newly added text in real-time on a separate client in Node.js without relying on socket.io?

I am in the process of creating a straightforward web application where users can input phrases. The app works fine, except for one issue - it doesn't display new additions from other users instantly. I am aware that socket.io could solve this problem ...

Learn how to retrieve URL parameters using HTML code

I would like to update the URL without refreshing the page as I am using an AJAX function to refresh a specific div. The issue I am encountering is that when the div is reloaded via AJAX, it does not recognize the URL parameter. Below is my code (I have a ...

Encountering an issue with React JS Array Filtering: running into the error message "

I am encountering an error stating that includes is not a function, and the record.id is not being recognized in VS Code. I'm not sure where the problem lies? import React, { Component } from 'react' import axios from "axios" export de ...

What are the steps for skipping, sorting, and limiting with dynamoose?

After being familiar with MongoDB and mongoose, I am now exploring dynamoose for my app. In order to replicate the below-shown mongoose query using dynamoose, how can I write it? Specifically, I want to achieve the same functionality as the following mong ...

Which is better for your website: SSG vs SSR?

Currently, I am diving into Nextjs and constructing a website using this framework. The site includes both public pages, protected routes (like user dashboard, user project details, and general user data), as well as product pages. I have been pondering h ...

Foundation Unveil Modal hidden from view

I'm currently integrating modals using Foundation 5 in a Rails application. The issue I'm facing is that the modal only works when the page is not scrolled down. If you scroll to the bottom of the page and try to activate the modal by clicking ...

Tips for handling "req.file.path" in form data when a user does not select a file with multer

Hello, I am currently working on a social networking project using MERN Stack. In this project, users have the option to make a post with just text or to upload an image along with some text as a caption. However, a problem arises when a user decides not t ...

struggling with responseText functionality in javascript

I am encountering an issue with passing variables from PHP to JavaScript using JSON. The problem lies in the fact that I am able to debug and view the items in the responseText within my JavaScript, but I am unable to assign them to a variable or properly ...

Bootstrap form validation solution

Utilizing bootstrap validation to validate a jsp page. The folder structure is as follows: WebContent ├── bootstrap-form-validation ├── js └── pages All three folders are under the web content. If I create another folder called teacher ...

Removing data with the click of a button

I have successfully implemented a feature where clicking the "add to my stay" button displays the name and price data. Subsequently, it automatically changes to a remove button when clicked again for another addon. If I press the remove button of the first ...

Utilizing Angular's ng-Grid with Promises

My current setup involves fetching a JSON file through a service to serve as the data source for my grid. The service successfully fetches the data, and the grid renders its basic layout correctly. However, there seems to be an issue with populating the gr ...

"Utilizing Expressjs to implement middleware cascading from one middleware to another

Routes Configuration var router = require('express').Router(); router.get('/all', require('./all')); module.exports = router; Successful Response in all.js module.exports = function(req, res, next) { res.send('The r ...

How to iterate through an array of objects in Javascript and extract an array of strings

I am dealing with an array of objects that looks like this: [{"key":"aaa","value":true},{"key":"bbb","value":false},{"key":"ccc","value":true}] My goal is to iterate through it and extract an array containing only the keys: ["aaa", "bbb", "ccc"] I am u ...

What is the process for reporting a security vulnerability in an npm package if you are the maintainer and publisher?

If I discover a security flaw in my published packages, how can I indicate which versions are vulnerable so that users running `npm audit` will be alerted? ...

Is it possible to use v-if in conjunction with a style tag to specify a different source file? Alternatively, is there a more efficient method I

I attempted the example provided below, but unfortunately, it did not function as expected. The reason behind my endeavor is that adding numerous modifiers (--tuned) to achieve the desired outcome seemed impractical. Therefore, I decided to try and link ...

How to disable annoying browser ad extensions using Javascript

Is there a way to prevent browser add-ons from injecting HTML code? My website built in angularjs is experiencing routing issues due to certain browser add-ons. The following HTML snippet is causing errors in my angularjs: <script async="" src="http:/ ...

The success function in Ajax is constantly elusive, while the error function prevails. The data just can't seem to make it to the destination file

Thank you for your patience. This marks my initial post to the best of my recollection. The section below showcases a snippet from my calendar.js script. My current objective involves sending data obtained from a modal window in index.php over to sql.php. ...