Assistance with a Loop

So I am very new to working in MongoDB I have some background using SQL in a relational database.

So I am trying to utilize a loop or a foreach statement to create two new records in one collection for each organization ID I have in another collection. As I stated, I am very new to MongoDB and looking for any and all assistance or ideas.

I have scoured the MongoDB website and google but I am just not able to put one to another. The link between the two collections is the organization ID in one collection it is an embedded record and the other collection it is not.

So you have an existing collection with records with organization ID (sample document please?) and you want to create two new records in another (existing?) collection - what would be in those records? It’s hard to help without knowing more details. It’s possible that what you are trying to do can be done with aggregation pipeline with $merge stage but I cannot say for sure without knowing more details…

Asya

1 Like

Hello,

Thank you for the quick response and my apologies for not adding more information. So I would be using the organization Id in the following example from one existing collection.

  "_organization" : {
        "id" : "d65ff080-23c3-11ed-b98c-519bf1f3431f",
        "type" : "Organization"
    },

Then on the other existing collection, I would be creating two new records linked to the organization Id the records would look like this for example:

{
    "_id" : "254480e5-7d32-4756-b748-120da9ef5f2b",
    "locationIds" : [ 
        "*"
    ],
    "roomIds" : [ 
        "*"
    ],
    "signageListIds" : [ 
        "*"
    ],
    "signageIds" : [ 
        "*"
    ],
    "deviceIds" : [ 
        "*"
    ],
    "type" : "Role",
    "name" : "Admin",
    "description" : "Admin Role",
    "organizationId" : "ec5b8680-f63a-11ec-a078-253419036b28",
    "application" : {
        "receivers" : 2,
        "rooms" : 2,
        "locations" : 2,
        "signage" : 2,
        "alerts" : 2,
        "organization" : 2,
        "billing" : 2,
        "users" : 2
    },
    "readOnly" : true,
    "createdAt" : ISODate("2022-06-27T17:02:27.904Z"),
    "updatedAt" : ISODate("2022-06-27T17:02:27.904Z"),
    "__v" : 0
}

/* 3 */
{
    "_id" : "745f0dde-40c8-40b0-9000-54fedbb62875",
    "locationIds" : [ 
        "*"
    ],
    "roomIds" : [ 
        "*"
    ],
    "signageListIds" : [ 
        "*"
    ],
    "signageIds" : [ 
        "*"
    ],
    "deviceIds" : [ 
        "*"
    ],
    "type" : "Role",
    "name" : "User",
    "description" : "No access to users or billing.",
    "organizationId" : "ec5b8680-f63a-11ec-a078-253419036b28",
    "application" : {
        "receivers" : 2,
        "rooms" : 2,
        "locations" : 2,
        "signage" : 2,
        "alerts" : 2,
        "organization" : 2,
        "billing" : 0,
        "users" : 0
    },
    "readOnly" : true,
    "createdAt" : ISODate("2022-06-27T17:02:27.904Z"),
    "updatedAt" : ISODate("2022-06-27T17:02:27.904Z"),
    "__v" : 0
}

I would need to create two new records for each distinct organization Id.

Where is the data in these new records coming from?

So the script I am writing is to take the current data from one collection and link it to the newly created records in the other collection.

would you be available for an email exchange?

We keep the discussions in the public forums so that everyone can learn.

It’s not really clear to me whether there are two collections involved or three, I’ll assume three - one with org, one with some current data you refer to as “current data from one collection”, and then there’s a third collection into which you are trying to insert two new documents… If that’s not the current schema, you’ll need to clarify. Since you’re inserting into an existing collection, there’s also a question about what you want to do if the equivalent record already exists. Maybe (simplified) actual sample records (that are input and that you want to generate as output) would clarify things.

Based on your comment

It sounds like you would just use $lookup to join the data in two collections.

Example org document:

{ "_id" : ObjectId("6309063722a3b8c70e43a64e"), 
"_organization" : {
     "id" : "d65ff080-23c3-11ed-b98c-519bf1f3431f", 
     "type" : "Organization", 
     "field1" : "xxx" } 
}

Example “other” collection:

{  "type" : "Role",
   "name" : "Admin",
   "description" : "Admin Role",
   "organizationId" :  "d65ff080-23c3-11ed-b98c-519bf1f3431f"
}

Now this aggregation

db.org.aggregate( [ {$lookup:{
    from:"other", 
    localField:"_organization.id", 
    foreignField:"organizationId", 
    as:"other"
}}])

will result in this output:

{  "_id" : ObjectId("6309063722a3b8c70e43a64e"),
   "_organization" : {
	"id" : "d65ff080-23c3-11ed-b98c-519bf1f3431f",
	"type" : "Organization",
	"field1" : "xxx"
   },
   "other" : [
	{
		"_id" : ObjectId("6309090b22a3b8c70e43a64f"),
		"type" : "Role",
		"name" : "Admin",
		"description" : "Admin Role",
		"organizationId" : "d65ff080-23c3-11ed-b98c-519bf1f3431f"
	}
]}

Presumably there are other fields in org - but once you clarify the full problem statement, we can proceed from there. Suffice it to say (for now) that I don’t see why you would need to do this in code on the client/application side - you should be able to do this inside the database assuming all these collections are in the same database.

Asya

1 Like

OK let me try to type this out a little better on my part.

I have two collections a db.users collection and a db.roles collection.

The data on the user collection look like the following:

/* 1 */
{
    "_id" : "d65eb800-23c3-11ed-b98c-519bf1f3431f",
    "is_active" : true,
    "is_verified" : true,
    "crm_id" : null,
    "role" : "admin",
    "ownerSetMFA" : false,
    "orgSwitching" : false,
    "type" : "User",
    "verification_code" : "2db0961b-f67c-49d9-ac2b-0b2140a3136c",
    "name" : "Josh test8",
    "email" : "test+test8@test.com",
    "phone" : "5555555555",
    "jobDescription" : "Administrator",
    "migrated" : true,
    "_organization" : {
        "id" : "d65ff080-23c3-11ed-b98c-519bf1f3431f",
        "type" : "Organization"
    },

with the data on the roles collection looking like this:

{
    "_id" : "254480e5-7d32-4756-b748-120da9ef5f2b",
    "locationIds" : [ 
        "*"
    ],
    "roomIds" : [ 
        "*"
    ],
    "signageListIds" : [ 
        "*"
    ],
    "signageIds" : [ 
        "*"
    ],
    "deviceIds" : [ 
        "*"
    ],
    "type" : "Role",
    "name" : "Admin",
    "description" : "Default Ditto Admin Role",
    "organizationId" : "ec5b8680-f63a-11ec-a078-253419036b28",
    "application" : {
        "receivers" : 2,
        "rooms" : 2,
        "locations" : 2,
        "signage" : 2,
        "alerts" : 2,
        "organization" : 2,
        "billing" : 2,
        "users" : 2
    },
    "readOnly" : true,
    "createdAt" : ISODate("2022-06-27T17:02:27.904Z"),
    "updatedAt" : ISODate("2022-06-27T17:02:27.904Z"),
    "__v" : 0

The roles collection is a new collection that was created due to a new feature that was created. We are creating two roles for every organization ID on the users collection an Admin and a User role. So I am working to write a script that will look for the distinct organization id on the user collection and work to created the two roles on the roles collection.

On the roles collection the _id field will be a UUID that is unique to the role.

Does that make a little more sense?

This makes a little more sense though I don’t know whether your roles for different organizations are going to be all the same or not - presumably they won’t be because otherwise why have different documents for each organization, but I guess you may be planning on populating these different fields later?

First thing you’ll want to do is to get every unique organization id from the users collection - probably either using aggregation, or using distinct command on "_organization.id".

If you want to do this in your client code, then just loop over each distinct organization id creating (inserting) two documents for each. That seems pretty straight forward, so I’m probably still missing what the challenge/tricky part is. When you go down this path, where is the next obstacle?

Asya