Minimize MongoDB aggregation using specific criteria

I am facing a challenge with my array of objects named "extra" that have different properties: some objects include the property "plus" while others do not. I am attempting to split this "extra" array into two separate arrays - one called "cheap" containing objects without the "plus" property, and another named "exp" which includes only objects with the "plus" property. I believe I can achieve this using the $reduce method in MongoDB aggregate along with $concatArrays by using $cond to check for the existence of the "plus" property. Here is an example of what I have tried:

Example data:

{
    extra: [
        {
            description: "laces",
            type: "exterior",
            plus: '200'
        },
        {
            description: "sole",
            type: "interior"
        },
        {
            description: "logo",
            type: "exterior"
        },
        {
            description: "stud",
            type: "exterior",
            plus: '450'
        }
    ],
}
 {
    $project: {
        extra: {
            $reduce: {
                input: ['$extra'],
                initialValue: {cheap: [], exp: []},
                $cond: {
                    if: {$eq: ['$$this.plus', null]},
                    then: {
                        in: {
                            cheap: {
                                $concatArrays: ['$$value.cheap', '$$this'],
                            },
                        },
                    },
                    else: {
                        in: {
                            exp: {
                                $concatArrays: ['$$value.exp', '$$this'],
                            },
                        },
                    },
                },
            },
        },
    },
}    

Despite trying several variations of the $cond section, I have been unsuccessful in getting it to work. Any assistance would be greatly appreciated. Thank you, K.

Answer №1

Aside from some minor syntax errors, there is another issue with your understanding of the $ne operator.

In this scenario, you are assuming that a missing value should be treated as equal to null. However, this is not how MongoDB operates. For example, given a document:

{ name: "my name" }

The aggregation query:

{ $cond: { $eq: ["$missingField", null] } }

Will not result in true as anticipated because a missing field is not equivalent to null. I have taken the initiative to correct the syntax errors and provide a functional pipeline:

db.collection.aggregate([
  {
    $project: {
      extra: {
        $reduce: {
          input: "$extra",
          initialValue: {
            cheap: [],
            exp: []
          },
          in: {
            cheap: {
              "$concatArrays": [
                "$$value.cheap",
                {
                  $cond: [
                    "$$this.plus",
                    [],
                    [
                      "$$this"
                    ],
                    
                  ]
                }
              ]
            },
            exp: {
              "$concatArrays": [
                "$$value.exp",
                {
                  $cond: [
                    "$$this.plus",
                    [
                      "$$this"
                    ],
                    []
                  ]
                }
              ]
            }
          }
        },
        
      },
      
    },
    
  }
])

Mongo Playground

It's important to note that the $cond function evaluates the plus field. This means if the field exists but has a null value or a value of 0, it will still consider the document as a match for the cheap array. Keep this in mind and make adjustments accordingly.

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

AngularJS data retrieval timeout function

After reading this response, I am currently in the process of developing a service that can provide data even if the request fails due to timing out. this.getStatus = function() { var timeoutPromise = $timeout(function () { cancele ...

Check to see if the item is not already in the cart, and if so, add it and then increase its quantity

Utilizing React context, I have implemented a simple logic to add products to the cart using the useReducer hook for adding items. If we look at the Redux Toolkit implementation, here is my redux logic: const cartItemSlice = createSlice({ name: " ...

Declare the push method within the Countly.q array in a TypeScript declaration file

Is there a way to declare Countly push add_event method in the following manner? Countly.q.push(['add_event',{ "key":"action_open_web", }]); I attempted to do this inside a declaration file (.d.ts) but it did not work. Here ...

Rotation of objects around a sphere in Three.js

Recently, I've been delving into threejs and encountered some challenges while attempting to rotate a globe with miniature spheres on its surface. If you're interested, you can find my code here: https://github.com/rohanbhangui/globe-webgl For ...

Is there a way to access the state value within the reducer function of createSlice?

Currently, I am utilizing redux-toolkit within my react project. A concern arises in a specific reducer inside the createSlice method where I aim to incorporate an existing array of entities from the state and then merge it with a new array before finalizi ...

I prefer the user not engage with the background when the jQuery dialog is displayed

When a user clicks on an external link, the jQuery UI dialog box will appear with "ok" and "cancel" buttons. Upon clicking "ok," the user should be directed to the external site. Although everything is functioning correctly, there is an issue with the mod ...

I require integrating another element alongside this button

I am trying to create a button component that, when clicked, will display another component along with it. However, I am unsure of how to achieve this. Take a look at the plantioComp return - this is the component that I want the button to trigger. <t ...

Ways to eliminate text following a string substitution

When running the code below with keys assigned to summer, spring, fall, and winter, the output for ins would be: ['req.body.summer, req.body.spring, req.body.fall, req.body.winter'] I need to eliminate the surrounding string from the replace co ...

Determine the number of properties present in two arrays by comparing them

Looking to compare two arrays and determine the count of items in the master list. A sample master list could be: { name: 'Emily', age: 29 }, { name: 'Jack', age: 31 }, { name: 'Lily', age: 28 }, { name: 'Emily', a ...

What causes a function to be returned as null when it is appended or assigned as textContent?

There's something I've been trying to figure out and I'm curious to get an answer on why it behaves this way. const print_html = (param) => { let container = document.querySelector('Container'); console.log(test_function(pa ...

Neglecting to send a socket signal while assigning a variable to a socket message

In my client-side script, I am using the following snippet: socket.on('bla', function(data) { if (data == ID) { console.log('I don't understand what's happening here.'); } }) socket.on(ID, function(data) { ...

What is preventing jQuery UI from detecting jQuery?

I have successfully created a JavaScript widget that is capable of being embedded on any third-party website, in any environment. The widget relies on jQuery and jQuery UI for its functionality. After following the guidelines outlined in How to embed Javas ...

cPanel is incompatible with node version 12.16.0

I am facing a dilemma regarding hosting my node API, which was built using node version 12.16.0, on cPanel. The available version for node in cPanel is 12.9.0 (Most recent). How should I proceed? Is the node version really a critical factor in this case? ...

Triggering AWS Lambda functions with SQS

Utilizing AWS and SES for sending emails and SMS through a Lambda function using NodeJs. I need to make more than 1k or 500 REST API calls, with the average call taking 3 seconds to execute a single lambda function request. It is essential to process mul ...

Printing doesn't display CSS styling

I am currently working on creating a function to change the font color, however, I am facing issues with the CSS when it comes to printing. Here is the code I have: $('#draw').on('click', 'p', function () { if($(this).ha ...

remove CSS attribute from the JavaScript DOM properties

Can someone help me figure out what's wrong with my code? I need to remove all "link" tags with the attribute "rel = "stylesheet" Here is the HTML code I am working with: <html> <head> <title>teset</title> <meta charset="u ...

In Vue JS, what is the best way to update a Child component after clicking a button on the Parent Component?

In my application, I have a setting option that updates from the Parent Component. The setting data is saved in localStorage and three Child Components utilize this setting data. <P> <c1> </c1> <c2> </c2> <c3> < ...

Why am I receiving the error message "Argument of type 'number' is not assignable to parameter of type 'never'?"

import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { showSecret = false; logArr ...

Utilizing props for toggling the navigation list, incorporating nested arrays or objects

My issue involves two components that are loading data. I want the links to be output like this: group1 linka linkb However, they are currently displaying like this: group1 linka group1 linkb I believe the problem lies in how I am handling the ...

Ways to refresh a webxr session while clearing all models from the scene

Whenever the webxr session restarts, I notice that two instances of previous objects appear on the screen. I want the screen to be clear when the session restarts. Currently, I am using the following code: for( var i = scene.children.length - 1; i >= 0 ...