Add the value to the array in MongoDb only if it does not already exist in

Looking to make updates to a nested array within a document only if the item is not already included in the array:

await userCollection.findOneAndUpdate(
    { _id: ObjectId('616acc597ebda90ca6ffee21') },
    {
      'devices': {
        $push: {
          $cond: {
            if: {
              $in: [req.body.serial, '$devices']
            },
            then: '$devices',
            else: { serial: req.body.serial, data: [] }
          }
        }
      }
    },
    { returnOriginal: false },
    (err, _) => {
      if (err) {
        return res.status(400);
      } else {
        return res.status(200).json(user.value);
      }
    }
  );

This represents my user object structure:

{
    "_id": "616acc597ebda90ca6ffee21",
    "username": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f783928483b783928483d994989a">[email protected]</a>",
    "displayName": "Test",
    "devices": [
      {
        "serial": "865674036421275",
        "data": [
          {
            "timestamp": "2021-10-16T12:36:35.799Z"
          },
          {            
            "timestamp": "2021-10-16T12:41:33.633Z"
          },
          {           
            "timestamp": "2021-10-16T12:52:03.055Z"
          }
        ]
      },
      
    ],
    "hashedPassword": "R5vt3vY7vEvTHvhC7YGNOWuIjBUQGLqsd92QGE06tjU=",
    "salt": "6RS0OVIFboCkIEPHdZmTcQ==",
    "dateCreated": "2021-10-16T12:58:00.294Z"
  }

Is there a method to verify if the serial already exists within devices? And can an error be triggered if it does?

Answer №1

Task

  • Locate and modify documents that do not contain a specific serial number
    (using the eq/ne query operators to check if an array contains a certain value)
  • Replace the current serial with the desired serial number
  • Add the new entry at the end of the array
  • The updateOne method will provide the result, indicating whether the update was successful or not. Refer to your driver's documentation for more details.

*This process is efficient as it targets a specific document based on the matching _id, eliminating the need for an index on devices.serial

Try out the code snippet here

db.collection.update({
  "_id": ObjectId("616acc597ebda90ca6ffee21"),
  "devices.serial": {
    "$ne": "000"
  }
},
{
  "$push": {
    "devices": {
      "serial": "000",
      "data": []
    }
  }
})

It's important to note that update operators cannot be combined with aggregate operators. The $cond operator, which is used in aggregation, cannot be mixed with the $push update operator. (The aggregate $push is designed for grouping operations and cannot add elements to an array)

While updates can be performed using update pipelines, a standard update operation suffices in this scenario.

Answer №2

To add elements to an array in MongoDB, you can use the addToSet operator. More information on how to use it can be found here

Answer №3

Performing a MongoDB Raw Query

db.userCollection.updateOne({
    _id: ObjectId('616acc597ebda90ca6ffee21'), // Ensure that the ID is in Object Id format
    "devices.serial": {$ne: "SerialNeedToMatch" }
}, {
    $push: {
        "devices": {
            serial: '111' // Add new serial number or complete object 
        }
    }
})

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 Interval Functionality Malfunctioning

I'm brand new to Vuejs and I'm attempting to set an interval for a function, but unfortunately it's not working as expected. Instead, I am encountering the following error: Uncaught TypeError: Cannot read property 'unshift' of u ...

javascript with a focus on objects

Having trouble with the scene.add(Obj); line for my object player1. I keep getting an error saying that Obj does not exist: function Player(x, y, z) { this.Speed = 0; this.AngleAcc = 0; this.Angle = 0; this.X=x; this.Y=y; this.Z=z; this.MaxSpeed = ...

Updating documents in a mongoDB collection can be done by simply

I require an update to my database that will modify existing data, as illustrated below: existing data => [{_id:"abnc214124",name:"mustafa",age:12,etc...}, {_id:"abnc21412432",name:"mustafa1",age:32,etc...}, {_id ...

Populate Chart.js with a specific set of JSON data

As I delve into the world of JavaScript, I'm faced with a challenging issue that I need help resolving: I have a JSON file housing an array of data. What I aim to do is extract specific arrays from the month of August (Reports, Average, Global) and d ...

Establishing a minimum date based on the date selected in the earlier datepicker

My webpage features two date pickers, one for startdate and the other for enddate. The current setup requires that the second datepicker remains inactive until a change is made to the first one. The datepicker for enddate is initially set with the startin ...

Load data onto a dropdown menu using Ajax requests

My view currently includes a dropdown menu. Upon selecting an item from the dropdown, AJAX is supposed to load. The table 'locations' has a one-to-many relationship with 'contacts.' When I select a location from the locations dropdown, ...

Pagination in DynamoDB: Moving forward and backward through your data

Currently, I am utilizing DynamoDB in combination with NodeJS to display a list of objects on the user interface. Given that DynamoDB can only process 1MB of data at a time, I have opted to implement pagination. This allows users to navigate between pages ...

NextJS hot reload with Docker is a powerful combination for seamless development environments

I've encountered issues trying to configure hot reload with Docker and NextJS. When I make changes and save a file, the server does not reload. Below is the contents of the docker-compose.yml: version: '3' services: mainapp: build: ./ ...

The Angular 5 keyup event is being triggered twice

My app is incredibly simple, just a basic hello world. To enhance its appearance, I incorporated bootstrap for the design and ng-bootstrap for the components. Within one of my TS files, you will find the following code: showMeTheKey(event: KeyboardEvent) ...

React is unable to identify the prop `controlID` when used on a DOM element in React-Bootstrap Forms

While constructing a form with React components sourced from react-bootstrap, and taking guidance directly from an example provided in its documentation: <Form.Group controlId="formBasicEmail"> <Form.Label>Email address</Form.Label> ...

Unable to change the color of the RaisedButton component in Material-UI

Struggling to alter the color of the material-ui RaisedButton with inline style customization using backgroundColor: '#fb933c', yet it continues to display the default color. ...

Angular's observable function is not providing a complete response

In my Angular component, I have a function that is called from a template. This function returns an Observable of type string, but unfortunately it only returns the `data` variable. How can I modify it to return `dateNew[0] + " de " + data + " de "+ dateNe ...

How to retrieve the ID of a parent sibling using jQuery DataTables

I have encountered a peculiar issue while trying to retrieve the ID of a table's parent sibling. Prior to initializing jQuery DataTables, obtaining the table's ID poses no problem. However, once it is initialized and the table is built, retrievin ...

Issue with V-checkbox input-value not triggering correctly on change

Query Example: <query #[`${instanceItemIdKey}`]="{ item }"> <v-checkbox :input="item.content" @modify="$notify('onPermissionUpdate', item)" ></v-checkbox> </query> The information that influ ...

Avoiding Webpack externals when using library components / fragments

Using Webpack has been a game-changer for us when it comes to writing isomorphic Javascript. It allows us to seamlessly switch between using npm packages on Node.js and utilizing browser globals during bundling. If I want to include the node-fetch npm pac ...

Prevent the default scroll event triggered by the mousewheel in certain situations. It is not possible to use preventDefault within a passive event

I have a div element with the onWheel attribute. By default, the browser interprets onWheel as scroll behavior. However, I want to prevent the browser's default mouse behavior under certain conditions. Unfortunately, I encountered an error that say ...

How can you access the input value from load dash's debounce function in a Vue.js application?

Is there a way to capture the input entered during the @typing event of the b-autocomplete component in Buefy? During the @typing event, the debounce method is called with specific parameters as shown below- <b-field label="Location"> ...

What is the best way to change a variable in an AngularJS view?

My Request In my application, I have implemented 3 views, each with its own controller. The first view is the home screen, and from there the user can navigate to view 2 by clicking on a div element. On view 2, the user can then move to view 3 by clicking ...

tips for efficiently using keyboard to navigate through tabs in an unordered list

Utilizing unordered lists in this web application. I am looking to implement tab navigation with keyboard functionality. How can I achieve this? The first tab should contain text boxes, and when the user fills out a text box and presses the tab key, they s ...

When utilizing json.loads in Python 2.7, it yields a unicode object rather than a dictionary

I'm currently facing a challenge with converting JSON data into a dictionary, and I'm struggling to find a solution. My situation involves connecting to a Tornado websocket from JavaScript and sending the following data inputted into a textfield ...