How can I determine the number of unique values in MongoDB?

I have a compilation of records that contain various feedback for different products. The structure is as follows:

{
  {
    item: "item_1"
    rating: "neutral"
    comment: "some comment"
  },
  {
    item: "item_2"
    rating: "good"
    comment: "some comment"
  },
  {
    item: "item_1"
    rating: "good"
    comment: "some comment"
  },
  {
    item: "item_1"
    rating: "bad"
    comment: "some comment"
  },
  {
    item: "item_3"
    rating: "good"
    comment: "some comment"
  },
}

My goal is to determine the frequency of each rating for every item.

Therefore, the desired output should be something like this:

{
  {
    item: "item_1"
    good: 12
    neutral: 10
    bad: 67
  },
  {
    item: "item_2"
    good: 2
    neutral: 45
    bad: 8
  },
  {
    item: "item_3"
    good: 1
    neutral: 31
    bad: 10
  }

}

This is what I have attempted so far

db.collection(collectionName).aggregate(
          [
             {
               $group:
                 {
                   _id: "$item",
                   good_count: {$sum: {$eq: ["$rating",  "Good"]}},
                   neutral_count:{$sum: {$eq: ["$rating",  "Neutral"]}},
                   bad_count:{$sum: {$eq: ["$rating",  "Bad"]}},
                 }
             }
           ]
)

The format of the output appears correct, but the counts are consistently 0.

I am curious about the appropriate method to total the occurrences based on the distinct values within the same field?

Thank you!

Answer №1

Although you were very close, keep in mind that $eq simply returns a true/false value. To convert this into a numeric value, you can utilize $cond:

db.collection(collectionName).aggregate([
  { "$group" : {
       "_id": "$item",
       "good_count": { 
           "$sum": { 
               "$cond": [ { "$eq": [ "$rating",  "good" ] }, 1, 0] 
           }
       },
       "neutral_count":{
           "$sum": { 
               "$cond": [ { "$eq": [ "$rating", "neutral" ] }, 1, 0 ]
            }
       },
       "bad_count": { 
           "$sum": { 
               "$cond": [ { "$eq": [ "$rating",  "bad" ] }, 1, 0 ]
           }
       }
  }}
])

Viewed as a "ternary" operator, $cond evaluates a logical condition as its first argument (if), returning the second argument for true outcomes (then) and the third argument for false outcomes (else). This conversion allows the true or false outputs to be converted into 1s and 0s for use with $sum.

Additionally, it's important to remember that "case" sensitivity matters when using $eq. If case variations are present, consider incorporating $toLower in the expressions:

               "$cond": [ { "$eq": [ { "$toLower": "$rating" },  "bad" ] }, 1, 0 ]

Shifting gears slightly, the following aggregation method is usually more adaptable to different values and significantly outperforms conditional sums:

db.collection(collectionName).aggregate([
    { "$group": {
        "_id": { 
            "item": "$item",
            "rating": { "$toLower": "$rating" }
        },
        "count": { "$sum": 1 }
    }},
    { "$group": {
        "_id": "$_id.item",
        "results": {
            "$push": {
                "rating": "$_id.rating",
                "count": "$count"
            }
        }
    }}
])

This approach would yield results similar to the following output:

{
    "_id": "item_1"
    "results":[
        { "rating": "good", "count": 12 },
        { "rating": "neutral", "count": 10 }
        { "rating": "bad", "count": 67 }
    ]
}

While conveying the same information, this alternative method eliminates the need to explicitly match values and operates far more efficiently.

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

Stop the webpage from refreshing using JavaScript

Similar Query: prevent postback of HtmlButton in C# This is the JavaScript function I'm using: <script type = "text/javascript"> function CheckForEmptySearchBox(id) { var index = id.substring(id.length - 1); var boxCont ...

What are the steps to position this bootstrap drop-down menu above a fixed page header?

Could someone please advise on what changes need to be made in the code snippet below from http://jsfiddle.net/ufkkdbja/? I am looking to ensure that when the hamburger menu is clicked, the entire menu appears without being cut off by the fixed page header ...

Express.js Server Unable to Receive JSON Data from JQuery Ajax Post

I am new to working with Node.js and I'm trying to send JSON data from client side JavaScript to an Express.js server. Once I achieve this, I plan to use the data received by the server to fetch additional information from MongoDB. The client side cod ...

guide for interpreting a complex json structure

I'm attempting to extract data from a JSON file that has multiple layers, like the example below. - "petOwner": { "name":"John", "age":31, "pets":[ { "animal":"dog", "name":"Fido" }, ...

JavaScript Special Character Removal

It appears that a specific character is causing an issue for the library I am utilizing called xlsx-writestream when attempting to write an Excel file. Upon my investigation, I discovered that the problematic string is "pawe2". It seems fine at first glanc ...

The date functionality is malfunctioning on Internet Explorer 8

Below is the code snippet that functions well on Chrome: function calculateTimeDifference(str1,str3,str4) { var dym1 = str1.split("/"); var d=new Date(); var dym2 = d.getMonth() + 1 + " " + d.getDate() + " " + d.getFullYear() + " " + d.getHo ...

Which option is more beneficial for intercepting API data in Angular 6: interfaces or classes?

My API returns JSON data that is not structured the way I need it, so I have to make changes. { "@odata.context":"xxxxxx", "id":"xxxxxxxx", "businessPhones":[ ], "displayName":"name", "givenName":"pseudo", "jobTitle":null, "ma ...

Displaying a division when a button is pressed

Despite my best efforts, I can't seem to get the chosen div to show and hide when the button is pressed. <button id="showButton" type="button">Show More</button> <div id="container"> <div id="fourthArticle"> <i ...

What is the process of relocating JSON and JS code from within an HTML file to external files?

My goal is to separate JSON and JavaScript code from the HTML file by moving them into external files. The examples shown below were part of a test I conducted to verify that the data was being successfully imported. As I begin to include real data, the J ...

pull information from mongodb and connect it to google charts

I am looking to extract information from a MongoDB database to create a pie chart using Google Charts. In one scenario, I have a collection named "user" where each user has a boolean attribute called "paid." I want to calculate the number of paid and free ...

The database encountered a surprising issue with an illegal token: `db.run

Upon executing the following line of code db.runCommand({convertToCapped: "mail_logs", size: 29250000‬ }) within the Mongo Shell environment, an error message is displayed: Error: Line 1: Unexpected token ILLEGAL ...

Tick the checkbox to indicate that I want to insert an image in the adjacent column for the same row

Every time I click on the checkbox, an image should appear in the adjacent column for that specific row. Despite using the addClass() method and targeting the td, the image is appearing in all rows instead of just the selected one. Could somebody help me ...

"Utilizing the Mongo Aggregation Pipeline for Formatting Arrays: A Step-by-Step Guide

I am working with a document in an Aggregation Pipeline: [ { "mfe_average": [ [ true, 5.352702824879613 ], [ false, 3.2361364317753383 ], [ null, 2.67502718181920 ...

Sinon Stub generates varying values with each invocation

I'm pretty new to TypeScript and JavaScript, but I've managed to create a functioning VScode extension that I'm really happy with. However, I'm running into some issues with my Mocha tests. Here's a snippet of the code I'm str ...

Vue alert: A duplicate key with the value of '10' has been identified. This could potentially lead to an issue with updates

I've been encountering a persistent error that I can't seem to resolve: [Vue warn]: Duplicate keys detected: '10'. This issue is causing an update error in my application. Despite trying the following steps, the error continues to appe ...

npm encountered an issue: EPERM error - the operation is not permitted and cannot unlink the file

Operating System: Windows 10. NPM Version: 6.9.0 Node Version: 12.4.0 I am currently developing an Expo application. I am attempting to install all the necessary packages for my Expo application using 'npm install'. However, I encountered an err ...

Angular 4: Transform a string into an array containing multiple objects

Recently, I received an API response that looks like this: { "status": "success", "code": 0, "message": "version list", "payload" : "[{\"code\":\"AB\",\"short\":\"AB\",\"name\":\"Alberta&b ...

I am struggling to grasp the concept of how the g flag in JavaScript's string.match(regexp) method operates

In the JavaScript book "The Good Parts", there is an explanation of the method string.match(regexp): The match method works by comparing a string with a regular expression. Its behavior varies based on whether or not the g flag is present. Without the g ...

"The website seems to be experiencing some technical difficulties on Firefox, but I have switched to

I attempted to reset the text area after sending a message with the code below: $(document).keypress(function (e) { if (e.which == 13) { e.preventDefault(); var $form = $('#f1'); $.ajax({ url: $form.attr( ...

When running the command `npm install <node_module> --save`, the dependencies are not being updated as

<=== If you're facing the same issue, try reinstalling your computer to fix it ===> I recently had to reformat my computer and set everything up again. After reinstalling Node and NPM, I encountered some problems that are really irritating me. ...