Updating MongoDB documents with multiple fields by cross-referencing with another collection

I have a large number of documents in mongoDB that need updating. Here are a few examples of existing documents from the Users collection:

{ 
    "_id" : "549120bcf5115900124fb6e1", 
    "user" : "Tom", 
    "country" : "United Kingdom", 
    "province" : "North Yorkshire", 
    "city" : "York", 
    "organization" : "" 
},
{ 
    "_id" : "143184fbf5482260184ac6e2", 
    "user" : "Jack", 
    "country" : "Not Listed", 
    "province" : "", 
    "city" : "", 
    "organization" : "United Nations"
},
{ 
    "_id" : "1234567890123456748979", 
    "user" : "Sarah", 
    "country" : "Not Listed", 
    "province" : "", 
    "city" : "", 
    "organization" : "" 
},
{ 
    "_id" : "98765432411654987654", 
    "user" : "Mat"
}

Each document may contain values for country, province, and city fields, or just country and state.

  • a country, a province, and a city
  • or a country and a state

Here is a sample from the Countries collection:

{ 
    "_id" : "123456789", 
    "key" : "Not Listed",
    "uuid" : "ca55b53a-ef5b-43ed-90ed-b857f45ddb6d",    
    "organization" : [
        {
            "key" : "United Nations", 
            "uuid" : "1c4ae4c6-00c5-405d-98fa-ca7cc9edc72a"
        }, 
        {
            "key" : "FIFA", 
            "uuid" : "11cfe606-821f-40fb-b1d0-bb7f9abb21dc"
        }
    ], 
    "province" : [], 
},
{ 
    "_id" : "1123465498742", 
    "key" : "United Kingdom", 
    "uuid" : "d756e167-25ec-4aa9-b231-4dbf6d4bfce4",
    "organization" : [], 
    "province" : [
        {
            "key" : "North Yorkshire", 
            "uuid" : "73d07c77-eba4-4dfa-9ada-e0ba8d8a2d55",            
            "city" : [
                {
                    "key" : "York", 
                    "uuid" : "80fd18a6-c4eb-4fb9-b591-6cca62319ba7"
                }, 
                {
                    "key" : "Middlesbrough", 
                    "uuid" : "26a277c4-8640-4959-a64a-00f3727975f4"
                }
            ], 
        },
        {
            "key" : "Oxfordshire", 
            "uuid" : "f7b5a570-df42-4520-ba3a-8bdcdd00e7d4",            
            "city" : [
                {
                    "key" : "Oxford", 
                    "uuid" : "b931865c-a363-4958-b7e7-5503fe674eb0"
                }, 
                {
                    "key" : "Banbury", 
                    "uuid" : "b8d4c63a-75a9-4c3c-a4cd-d315f06a92e0"
                }
            ], 
        }
    ]
}

The goal is to update the country/organization/province/city field values in the Users collection based on the uuid value from the Countries collection.

The updated documents will look like this:

{ 
    "_id" : "549120bcf5115900124fb6e1", 
    "user" : "Tom", 
    "country" : "d756e167-25ec-4aa9-b231-4dbf6d4bfce4", // uuid of United Kingdom
    "province" : "73d07c77-eba4-4dfa-9ada-e0ba8d8a2d55", // uuid of North Yorkshire
    "city" : "80fd18a6-c4eb-4fb9-b591-6cca62...
},
{ 
    "_id" : "143184fbf5482260184ac6e2", 
    "user" : "Jack", 
    "country" : "ca55b53a-ef5b-43ed-90ed-b857f45ddb6d", // uuid of Not Listed
    "province" : "", 
    "city" : "", 
    ...
},
{ 
    "_id" : "1234567890123456748979", 
    "user" : "Sarah", 
    "country" : "ca55b53a-ef5b-43ed-90ed-b857f45ddb6d", // uuid of Not Listed
    "province" : "", 
    "city" : "", 
    ...
},
{ 
    "_id" : "98765432411654987654", 
    "user" : "Mat" 
}

The fields have dependencies as follows:

Country > Province > City

Or:

Country > Organization

It's possible for a parent field to exist without its child field being present.

Is there a way to update these multidimensional arrays using MongoDB script rules?

Here is my attempt, which involves multiple nested loops. I'm unsure how to handle the find/update/save part in MongoDB... Can anyone provide guidance on achieving this?

var usrCountry, uuidcountry, usrProvince, uuidprovince, usrOrg, uuidorg, usrCity, uuidcity;

for (var i = 0; i < users.length; i++) {
   usrCountry = users[i].country;
   usrProvince = users[i].province;
   usrOrg = users[i].organization;
   usrCity = users[i].city;
   for (var j = 0; j < countries.length; j++) {
     if (countries[j].key === usrCountry) {
       uuidcountry = countries[j].uuid;
       console.log('uuidcountry: ', uuidcountry)
       if (countries[j].province.length){
         for (var k = 0; k < countries[j].province.length; k++) {
           if (countries[j].province[k].key === usrProvince){
            uuidprovince = countries[j].province[k].uuid;
            console.log('uuidprovince', uuidprovince)
            for (var l = 0; l < countries[j].province[k].city.length; l++) {
             if (countries[j].province[k].city[l].key === usrCity){
               uuidcity = countries[j].province[k].city[l].uuid
               console.log('uuidcity: ', uuidcity)
             }
            }  
           }

         }
       }
     }
   }
}

Answer №1

If you want to achieve this using an aggregation pipeline and utilize the information for updates, you can follow the code below:

db.u.aggregate(
    [
        {
            $lookup: {
                from : "c",
                localField : "country",
                foreignField : "key",
                as : "countryInfo"
            }
        },
        {
            $project: {
                "_id" : 1,
                "user" : 1,
                "province" : 1,
                "country" : 1,
                "city" : 1, 
                "organization" : 1,
                "country_uuid" : {$arrayElemAt : ["$countryInfo.uuid",0]},
                "province_uuid" : { $arrayElemAt : [{ $map : { input : { $filter : {  input : {$arrayElemAt : ["$countryInfo.province" ,0 ]} , as : "pro", cond : { $eq : [ "$$pro.key", "$province" ]  } } } , as : "pr", in : "$$pr.uuid" } }, 0 ] },
                "city_uuid" : {$arrayElemAt : [{$map : { input : { $arrayElemAt : [ {$filter : { input : { $map : { input : { $arrayElemAt : ["$countryInfo.province.city" ,0 ] }, as : "ct", in : { $filter : { input : "$$ct" , as : "ctyy", cond : { $eq : ["$$ctyy.key", "$city"] } } } } }, as : "o", cond : {$ne : [ {$size : "$$o"} , 0  ] } } } , 0]}, as : "o", in :"$$o.uuid"}}, 0]}
            }
        }
    ]
)

This is the expected result:

> db.u.aggregate( [ { $lookup: { from : "c", localField : "country", foreignField : "key", as : "countryInfo" } }, { $project: { "_id" : 1, "user" : 1, "province" : 1, "country" : 1, "city" : 1,  "organization" : 1, "country_uuid" : {$arrayElemAt : ["$countryInfo.uuid",0]}, "province_uuid" : { $arrayElemAt : [{ $map : { input : { $filter : {  input : {$arrayElemAt : ["$countryInfo.province" ,0 ]} , as : "pro", cond : { $eq : [ "$$pro.key", "$province" ]  } } } , as : "pr", in : "$$pr.uuid" } }, 0 ] }, "city_uuid" : {$arrayElemAt : [{$map : { input : { $arrayElemAt : [ {$filter : { input : { $map : { input : { $arrayElemAt : ["$countryInfo.province.city" ,0 ] }, as : "ct", in : { $filter : { input : "$$ct" , as : "ctyy", cond : { $eq : ["$$ctyy.key", "$city"] } } } } }, as : "o", cond : {$ne : [ {$size : "$$o"} , 0  ] } } } , 0]}, as : "o", in :"$$o.uuid"}}, 0]} } } ] ).pretty()
{
    "_id" : "549120bcf5115900124fb6e1",
    "user" : "Tom",
    "country" : "United Kingdom",
    "province" : "North Yorkshire",
    "city" : "York",
    "organization" : "",
    "country_uuid" : "d756e167-25ec-4aa9-b231-4dbf6d4bfce4",
    "province_uuid" : "73d07c77-eba4-4dfa-9ada-e0ba8d8a2d55",
    "city_uuid" : "80fd18a6-c4eb-4fb9-b591-6cca62319ba7"
}

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

Modifying the state of one React component using another

Attempting to modify the state of one component using another component in ReactJs, however, being new to React. The parent component contains a state called: _SPCommandBarDisabled this.state = { _SPCommandBarDisabled: true } In a child component ...

The feature of scrolling to a specific element within a bootstrap modal is not functioning as expected

I recently encountered an issue while using a Bootstrap modal. The problem arose when I tried to scroll to a specific element within the modal, but my code didn't produce the desired results. $('#centralModalLg').on('show.bs.modal&apo ...

The importance of passing navigation to the App.js file in React Native

I recently went through the Auth Flow Tutorial for React Navigation and successfully implemented it. However, I'm facing an issue with the "navigation" part in export default function App({ navigation }). I need the navigation functionality in my App ...

How can I utilize the Camera function in Cordova?

I am in the process of developing a Cordova app that will be compatible with both iOS and Android platforms. One of the key features of the app is the ability to display a camera within a specified frame. Below the camera frame, there will be a button labe ...

Compel the browser to launch a fresh tab

I'm currently working on an app that involves uploading files. One issue I'm facing is that the file system pop up doesn't close after the upload, causing a quarter of the screen to be covered while the test keeps running in the background. ...

What is the best way to iterate through the second element using jQuery?

this is the object of my upcoming events let upcomingEvents = [{ id: '1', location: 'asd', dates: '2019-12-21 16:00:00-2019-12-21 17:30:00', position: '3', status: true, sessions: [{ ...

Transferring data from a React file to a plain HTML page

What is the best way to transfer information from a React app to a static HTML file? For instance, if I collect data through a form in a React app.js file, how can I then send that data to a basic HTML file? ...

Efficient utilization of data and maximizing the performance of loops

Looking at a hefty JSON object, here's a snippet: data = [ { 'make': 'dacia', 'model': 'x', 'version': 'A', 'typ': 'sedan', 'infos': [ ...

I'm stuck trying to figure out all the parameters for the MapsPage component in Angular 2

Currently, I am utilizing Angular2 with Ionic2 for my mobile app development. Everything was working flawlessly until I decided to incorporate a new module for Google Maps navigation. Specifically, I am using phonegap-launch-navigator for this purpose. The ...

When looking at react/17.0.1/umd/react.development.js, it becomes evident that ReactDOM is not defined

I'm currently immersing myself in learning React with the help of React Quickly, written by Azat Mardan, which is based on React v15.5.4. The examples provided in the book typically include two essential files: react.js and react-dom.js, such as in th ...

Sending Angular Material Select Option Value for Submission

HTML: <form id="reg" name="reg" enctype="application/x-www-form-urlencoded" action="http://api.phphotspot.com/v-2/client-register" method="post"> <md-input-container class="md-block"> <label for="country">Country</label&g ...

Is there a way to mount or unmount a React component by pressing a single key?

I am currently developing an application that showcases 3D objects upon pressing certain keys on the keyboard. My goal is to have these objects disappear after 2-3 seconds or once the animation completes. Below is the component responsible for managing th ...

Can we switch between using Vue components in .vue formats and commonJS formats seamlessly?

Here is the commonJS format: Vue.Component('custom-component',{ template : '<p>Some template</p>', data : {} methods : {} }); And here is the .vue format: <template> <p>Some template&l ...

Trigger the .focus() method on a neighboring VueJS Component

I am facing an issue with two independent components in my Vue instance. I have a select component and an input component, both of which are siblings. I need to trigger a focus event on the input component when the select component is changed. Since both ...

Understanding Joi validation - setting a field as optional depending on the input received

I have been struggling to integrate the following joi validation. joiSchema = Joi.object().keys({ taskno: Joi.string().alphanum().required().uppercase().trim(), taskstatus: Joi.valid('G', 'C', 'I', 'S'), ...

Combining multiple rows into one using either mysql or lodash was achieved by Node

Currently in my Javascript framework, I am utilizing the Node MySQL library for executing MySQL queries. I encountered an issue with a left join that resulted in multiple rows being returned. This is because the left join generates duplicate rows with diff ...

Issue with displaying mootools tooltips on Request.HTML content

I am encountering an issue with incorporating tips into a Request.HTML function. I have a div that updates its content every 30 seconds. The returned content consists of multiple divs with the class ".liveReader". Below is the JavaScript code used to init ...

Reorganize the elements in the array

Here is how the array is structured: Array ( [SMART Board] => Array ( [0] => sb1 [1] => sb2 [2] => sb3 ) [Projector] => Array ( [0] => pr1 [1] => pr2 [2] => pr3 ) [Speakers] => Array ( [0] => sp1 [1] => sp2 [2] =& ...

I've been working on a script in JavaScript to retrieve lectures for a specific day, but I'm having trouble connecting my jQuery code to it

Exploring a JavaScript function that retrieves today's lectures for a specific section of a class using jQuery. The challenge lies in implementing this array of classes on an HTML file. //function to get today var today = new Date(); var dd = today ...

Instructions on incorporating domains into next.config.js for the "next/image" function with the help of a plugin

Here is the configuration I am currently using. // next.config.js const withImages = require("next-images"); module.exports = withImages({ webpack(config, options) { return config; }, }); I need to include this code in order to allow images from ...