Adding a new field to an embedded document in MongoDB (without using an array)

My task involves updating a json document in mongodb by single field. Despite the simplicity if my data was in an object array, it's more complex due to objects within objects caused by early design choices and reasons.

This is the structure of the single document in my collection:

{
  "_id": 123123,
  "drivers_teams": { 
    "drivers" : { 
       "4" : { <data> },
       "5" : { <data indeed> },
       ...
    },
    ...
  }
 } 

I am aiming to add a new object like this:

const collection = db.get('collection');  
let drivers = { };  
drivers['111'] = { <new data> };

collection.update({}, {$set: { drivers_teams: { drivers } }}, { upsert: true }, function (err, doc) { ... });

However, the original objects in "drivers_teams" get wiped out and only the new field remains inside.

If I attempt:

collection.update({}, {$set: {  drivers }}, { upsert: true }, function (err, doc) { ... });

A new field "drivers" is inserted outside the drivers_teams.

{
  "_id": 123123,
  "drivers" : { <new data> },
  "drivers_teams": { <still original> }
 }

I encountered a similar issue (+solution) here but the json wasn't nested like mine. https://groups.google.com/forum/#!topic/mongodb-user/ZxdsuIU94AY

Is there any way to achieve what I'm attempting? Or should I resort to overwriting the entire document when updating a single field?

EDIT

The working solution is

{$set: { 'drivers_teams.drivers.111': <data> }}
. However, what I failed to mention is that the key '111' in the example is actually unknown as it comes from the client while sending update data. This is why the new object was created using this method: dynamically name mongo key field

Any attempts to write something like

{ 'drivers_teams.driver.' + key: <data> }
results in an error.

Answer №1

According to the documentation for '$set', specifying a field in an embedded document or array can be done using dot notation. In your scenario, you can achieve this by:

collection.update({}, 
   {
      $set: { "drivers_teams.drivers.111": { <new data> }}
   }, 
   { upsert: true }, function (err, doc) { ... });

https://docs.mongodb.com/manual/reference/operator/update/set/

Edit: If the field name is generated dynamically, you can try:

const collection = db.get('collection');
let set_obj= { };  
set_obj['drivers_teams.driver.' + key] =  { <new data> };

collection.update({}, {$set: set_obj }})

Answer №2

You forgot to include a level above the drivers sub-document. To achieve this in the mongo shell, you should execute the following command:

db.collection.update({}, {$set: {'drivers_teams.drivers.111': {...}}})

This operation will result in the document being updated as shown below:

{
  "_id": 123123,
  "drivers_teams": {
    "drivers": {
      "4": {...},
      "5": {...},
      "111": {...}
    }
  }
}

For more information on MongoDB's dot notation for embedded documents, please refer to the Embedded Documents page.

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

Attempting to trigger the timer to begin counting down upon accessing the webpage

Take a look at this example I put together in a fiddle: https://jsfiddle.net/r5yj99bs/1/ I'm aiming to kickstart as soon as the page loads, while still providing the option to pause/resume. Is there a way to show the remaining time as '5 minute ...

Tips on inserting commas between JSON entities found in a .txt file followed by transforming it into a JSON array using Python

When reading a .txt file containing JSON objects without commas separating them, I need to insert commas between the objects and convert them into a JSON list or Array. After attempting to use JSON.loads and encountering a JSON Decode error, I realized th ...

The task in gulp-run-sequence remains incomplete

The gulp-tasks I have set up are designed to revision static files and update the links to them. var config = require('./config'); var gulp = require('gulp'); var rev = require(& ...

Switching Profiles in XPages

In my Xpages project, I have two different user profiles set up. I am currently attempting to develop a function that would allow me to easily switch between these two profiles. However, I am unsure of the steps needed to accomplish this task. ...

Tips for triggering the onChange event in Formik and initiating a re-render of other components

As someone who is new to React, I am currently working on a webpage with 2 forms. The first form has only one input field while the second form is a component imported from another file. Despite trying to use onChange to update the initial value (initialVa ...

Retrieve the number of fields in every document with a query using the MongoDB Java driver

Can I retrieve the number of fields in a document using a Query from MongoDB Java Driver? For example: Document1 :{_id:1,"type1": 10 "type2":30,"ABC":123,"DEF":345} Document2 :{_id:2,"type2":30,"ABC":123,"DEF":345} Note: The second document does not c ...

Guide on transforming a JSON String into a Java object

When passing a JSON string from JSP to the server via AJAX call, I am converting it to a JSON object. How do I then convert this JSONObject into a model class object in Java? On the server side, I am doing the following: HttpServletRequest request = Ser ...

The presence of Vue refs is evident, though accessing refs[key] results in an

I am facing an issue with dynamically rendered checkboxes through a v-for loop. I have set the reference equal to a checkbox-specific id, but when I try to access this reference[id] in mounted(), it returns undefined. Here is the code snippet: let id = t ...

eliminate the firebase firestore query using onSnapshot

Seeking assistance with the following code snippet: firebase.firestore() .collection("chatrooms") .doc(`${chatId}`) .collection(`${chatId}`) .orderBy("timestamp") .limit(50).onSnapshot((snapshot) => { //performing oper ...

Retrieve a single instance of every element within an array using JavaScript

I have an array of player objects, each containing properties such as "position" and "player_name". With 8 unique positions available for players, I aim to extract the first player for each position and transfer them to a new array. This way, the new array ...

Dispose the inputpicker filter after setting the value

I am currently utilizing the "Jquery inputpicker plugin" for creating dropdown menus. More information about this plugin can be found here. To initialize my dropdown, I use the following code: $('#test').inputpicker({ data:[ {value:"1 ...

The AngularJS ng-if directive functions on a variable will only function on the

I'm currently working on updating an old codebase that was written in AngularJS, a framework I am not very familiar with. My task is to implement a spinner that appears when an HTTP request is sent and disappears once the response is received. The sp ...

What is the best way to utilize Text.JSON for parsing a string retrieved from a file within Haskell?

In my Haskell application, I am working on implementing a persistence system where I convert data structures to JSON format and save them to disk. The plan is to later read the file and use a JSON parser to reconstruct the objects. However, there seems to ...

Encountered a JSON decoding error while parsing data from an API that includes Japanese characters

While trying to handle an API response using Scrapy and JSON, I encountered the error json.decoder.JSONDecodeError: Despite experimenting with various Japanese encoding types listed here, none of them proved successful. I am hopeful that someone here migh ...

How to fetch a list of users in an organization from Azure DevOps using Python API call

I'm attempting to create a basic api call in Python to Azure DevOps to retrieve a list of users. The URL is returning results when accessed through a browser, but I am encountering an error while scripting it as shown below. I need assistance in prope ...

Using PHP and DOJO to transfer HTML via JSON

My data store is currently querying a database and outputting JSON in the following format: $data[] = array('id' => $i, 'prod_id' => $product_id, 'link' => $link); I am curious about how to include a link using the ...

Error message saying 'Callback has already been invoked' returned by an async waterfall function

I'm facing an error that I understand the reason for, but I'm unsure how to resolve it. Here's a breakdown of my initial function: Essentially, I am making a get request for all URLs stored in the database and then, for each URL response, I ...

Ways to Determine the Height and Width of an Image Once it has been Adjusted for a View

Is there a way to retrieve the height and width of an image after it has been resized for a view? I have images that may vary in original dimensions, but users can resize them as needed. For example, this code from the console gives the client height: do ...

Ways to join two if statements together using the or operator

Below is my code attempting to check if either child elements H1 or H2 contain text that can be stored in a variable. If not, it defaults to using the parent element's text: if($(this).children('h1').length){ markerCon[markerNum] = $(th ...

Utilizing Airflow's web API to generate a JSON variable

Attempting to set up a variable with a JSON value in Airflow using the web API. Here is my script: curl -X POST "${AIRFLOW_URL}/api/v1/variables" \ -H "Content-Type: application/json" \ --user "${AIRFLOW_USERNAME}:${AIRFLOW_PASSW ...