Setting a default field value in Mongoose when updating multiple documents at once

Issue:

Encountering problem with aggregation in a non-existent field.

I am working with the Follow Schema which has the following fields:

_user_id: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User',
        required: true
    },
    following: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User',
        required: true,
        default: []
    }],
    followers: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User',
        required: true,
        default: []
    }],

When a user follows someone, the code looks like this:

const bulk = Follow.collection.initializeUnorderedBulkOp();

bulk.find({ _user_id: req.user._id }).upsert().updateOne({
  $addToSet: {
     following: Types.ObjectId(follow_id)
  }
});

bulk.find({ _user_id: Types.ObjectId(follow_id) }).upsert().updateOne({
   $addToSet: {
     followers: req.user._id
   }
});

bulk.execute((err, doc) => {
  ...
})

However, when new data is being saved for the first time, the bulk operation saves only the specified $addToSet field. For instance, if I run this:

bulk.find({ _user_id: Types.ObjectId(follow_id) }).upsert().updateOne({
   $addToSet: {
     followers: req.user._id
   }
});

It will result in:

{
  _id: ObjectId(544987dfgsld3),
  followers: [ ObjectId(34578778g6d8f7g6) ] // Followers get saved
            // How can I initialize the following as an empty array? 
}

This leads to errors in aggregation because the field does not exist.

const result = await Follow.aggregate([
                {
                    $match: { _user_id: user._id }
                },
                {
                    $project: {
                        _id: 0,
                        followingCount: { $size: '$following' }, // Error occurs here - size field must be an array but it doesn't exist
                        followersCount: { $size: '$followers' },
                        followers: 1
                    }
                },
            ]);

Answer №1

Resolved the issue by ensuring that a non-existent field was being checked in my bulkOp query:

bulk
  .find({
     _user_id: Types.ObjectId(follow_id),
     following: { // included this section
        $exists: false
     }
})
.upsert()
.updateOne({
   $set: {  // utilizing the $set operator
     following: []
   }
});

Also, found a more streamlined approach using aggregate:

{
   $project: {
     following: { $ifNull: ["$following", []] }, // PROVIDE DEFAULTS IF FIELD IS NULL OR NOT PRESENT
     followers: { $ifNull: ["$following", []] },
     followers: 1
   }
},
{
  $project: {
    _id: 0,
    followingCount: { $size: '$following' },
    followersCount: { $size: '$followers' },
    followers: 1
   }
},

For additional information on the $ifNull Operator

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 retrieve all the selected values from multiple select inputs when a button is clicked in React?

I am currently working on developing a questionnaire where the select inputs' values are collected and averaged to generate a final score. Although it may sound simple, I'm facing difficulties in retrieving these values. At this point, my primary ...

Activate real-time highlighting by clicking on the search button

I created a simple program that searches for a value within a div and displays the first location of the word. However, I am looking to enhance it by highlighting all repeated locations of the searched word after pressing the search button. <html> & ...

Whenever I declare it, the onclick method is executed

I have been attempting to define an onclick method that would trigger a function to clear and reconstruct the display, revealing more detailed information about the clicked item. However, I am facing an issue where the assigned onclick method is executed i ...

How can certain HTML be redirected or hidden for users on mobile devices?

Lately, I've been putting the final touches on my website to present to potential employers as I will soon be starting my job search after graduation. I recently added an "about" section with parallax scrolling effect, but unfortunately, it's not ...

Looking to tidy up the HTML produced by JQueryUI?

Is there a way to achieve this? I am developing a template generator that includes resizable and draggable elements within a preview window. The issue arises when I try to extract the generated HTML, as it contains unwanted JQueryUI classes and divs for ea ...

The express server encountered an issue with setting headers after they have already been sent to the client, resulting in the error [ERR_HTTP

I am facing an issue while trying to save data in MongoDB using the "return" statement. Even after attempting with async-await, I am still encountering errors. Can anyone provide me with some assistance? Here is my code snippet: const votedOnSolModel = req ...

The use of '$or' operator in Mongodb query does not return any results

Something very strange is happening with my database. I ran a query: db.Tag.find({"word":"foo"}) This query successfully matches one object, which is great. However, when I run the second query: db.Tag.find({$or: [{"word":"foo"}]}) No results are retu ...

The JSON data response is not being properly displayed on the div element

I am having trouble with the success function in my ajax call. The data is processed correctly in the view and the ajax call works fine, but for some reason, the data is not getting appended to the div. Here is my jQuery: $(document).ready(function() { ...

Activate disk use permission in Node-RED

When attempting to execute an aggregated query in Node-RED, I encountered the following error message: MongoError: Sort exceeded memory limit of 104857600 bytes, but did not opt in to external sorting. Aborting operation. Pass allowDiskUse:true to opt i ...

Is it possible to invoke an AngularJs service by clicking a button?

Recently, I've been working on some AngularJS code involving a service and controller. angular.module('myModule', []).service("AttendanceService", function ($http) { this.getdata = function () { return $http({ ...

Navigating through content with scrollable views while utilizing the popular Angular framework

Being relatively new to famous and somewhat familiar with angular. Question: Given that everything in famous is fixed positioning, how should I go about creating a scrollable section using famous angular? HTML: This code snippet creates a grid of square ...

What is the best way to convert a requested JSON array into a CSV file using Python?

I'm completely new to programming and I'm having trouble saving my data. Currently, I'm working on a website for a scientific experiment where users are required to click 'yes' or 'no' buttons to indicate their recognitio ...

Guide to utilizing jQuery for setting values in all subsequent rows of a table

I have a table with 15 rows of text boxes labeled as text1, text2, and so on up to text15. If I enter text into, let's say, the 5th textbox, I want that same text to be automatically copied into all subsequent textboxes from the 6th through the 15th. ...

Populate a pair of div elements using just one AJAX request

Currently, I am attempting to use the load() function to ajaxly load two separate divs, #follow-x and #follow-y, by clicking a button. The approach I have taken is as follows within the success function of my code snippet. However, this method does not see ...

The innerHTML function is providing plain text instead of HTML content

I am currently working on an application in AngularJS and I have a function that removes #(hashes) and turns them into links. $scope.getAllHashes = function(event){ var x = event; var collect = ''; var link = ''; for ...

Creating a custom filter with ngx-pagination

Having trouble with filtering in Angular 7 + Electron 4 while using ngx-pagination. I followed the steps mentioned in the documentation, but encountered an error Uncaught Error: Template parse errors: The pipe 'stringFilter' could not be found ...

Altering HTML code using jQuery within an Angular app for a WYSIWYG editor

I am working with a wysiwyg editor that utilizes a $scope variable to generate HTML content. Currently, I am trying to dynamically add div elements at specific locations within the HTML string. This will allow me to programmatically modify different parts ...

Using ReactJS to capture keydown events from an iframe

I am trying to implement keydown event handling for an iframe within a ReactJS component. The iframe contains an embedded video, and I want to be able to capture keyboard events while the video is playing. Can someone please assist me with how to achieve ...

Instructions for assigning a key and value within a MongoDB array

I am managing a group of students who can establish friendships with other students. {name:'someone', email:'st', friends[ObjectId,ObjectId]} When I need to access the list of friends, I have to populate the object and search through ...

Achieving sequential actions in Javascript without the need for state updates

One aspect of jQuery that I find impressive is its ability to chain methods like .animate() and .css(). This is made possible by utilizing the special variable "this" in the backend code. I am interested in implementing a similar method chaining mechanism ...