MongoDB Realm - embedded array of objects not accessible in Mongo-Function via „FullDocument“

Hi all,

I’m new to the community.
I currently have an issue/problem where I’m struggling with. Maybe somebody has a good hint for me :slight_smile:

Enviroment:

MongoDB Realm
Version: 4.4.6
CLUSTER TIER: M0 Sandbox (General)
REGION: AWS / N. Virginia (us-east-1)

Description:

I want to watch out for changes in a special collection like in my example „User“-Collection.
Therefore I use a trigger in MongoDB Realm, which checks if a new entry will be inserted to the „User“ Collection.

If an entry will be inserted, the Trigger is firing and forwarding the „FullDocument“ to a Mongo-Function which will do some checks and further manipulation.

The (inserted) document in the collection has the following content as you can see in the enclosed example-dataset:

{
	_id: "606f48f6308c87387b529f17",
       	name: „Thomas“,
        friends: [
          {
            status: "Open",
            friend_userId:"606870420b4920e213f004b9",
            friend_username:“Sam“,
          },
          {
            status: "Open",
            friend_userId:“32rfd3sddsfb4920e21dsdsfg“,
            friend_username:“William“,
          }
        ],
        created_by: "606870420b4920e213f004b9",
}

Problem/Issue:

The „FullDocument“ within the Mongo-Function is receiving all the properties correctly and I can work with it, the only part of the document which is not included in the „FullDocument“ is the embedded array of Objects „friends“.

This object is unfortunately missing in the transmitted „FullDocument“ like you can see below:

{
	_id: "606f48f6308c87387b529f17",
       	name: „Thomas“,
        created_by: "606870420b4920e213f004b9",
}

Somebody already had the same issue or is it generally not possible to pass embedded arrays of Objects via „FullDocument“ to a Mongo-Function?

Thanks in advance and BR
JD

Hi @Dominik_Jell, welcome to the community!

I just ran a trigger test with your document, and it looks to be working fine.

This is the trigger function:

exports = function(changeEvent) {
  const fullDocument = changeEvent.fullDocument;
  console.log(`friend_username = ${fullDocument.friends[0].friend_username}`);
}; 

And this is the output:

Logs:
[
  "friend_username = Sam"
]

Perhaps you could share your function that’s not working as you expect?

Hi Andrew,

thanks for your feedback and explanation as well.
Sorry I’ve forgotten one hierarchy „friends_internal“ in my example.

The example, which is not working in my current project is the following:

{
_id: “606f48f6308c87387b529f17”,
name: „Thomas“,
friends: {
	friends_internal: [
		{
		status: “Open”,
		friend_userId:“606870420b4920e213f004b9”,
		friend_username:“Sam“,
		},
		{
		status: “Open”,
		friend_userId:“32rfd3sddsfb4920e21dsdsfg“,
		riend_username:“William“,
		}
	],
	friends_external [
		{
		status: “Open”,
		friend_userId:“976trf3243jg870420bwered”,
		friend_username:“Benjamin“,
		},
		{
		status: “Open”,
		friend_userId:“32rfd3sdredsfbewrewew“,
		friend_username:“Ivonne“,
		}
	],
},
created_by: “606870420b4920e213f004b9”,
}

As mentioned, I’m not able to iterate trough the „Friends_internal“ array, because this array-objects are „undefined“ in FullDocument.

should this work as well the same way?

Thanks in advance and best regards
Dominik

That document seems to work too…

exports = function(changeEvent) {
  const fullDocument = changeEvent.fullDocument;
  console.log(`friends_internal[0].friend_username = ${fullDocument.friends.friends_internal[0].friend_username}`);
};
db.User.insert(
    {
        name: "Thomas",
        friends: {
            friends_internal: [
                {
                    status: "Open",
                    friend_userId:"606870420b4920e213f004b9",
                    friend_username:"Sam",
                },
                {
                    status: "Open",
                    friend_userId:"32rfd3sddsfb4920e21dsdsfg",
                    riend_username:"William",
                }
            ],
            friends_external: [
                {
                    status: "Open",
                    friend_userId:"976trf3243jg870420bwered",
                    friend_username:"Benjamin",
                },
                {
                    status: "Open",
                    friend_userId:"32rfd3sdredsfbewrewew",
                    friend_username:"Ivonne",
                }
            ]
        },
        created_by: "606870420b4920e213f004b9",
    }
)
Logs:
[
  "friends_internal[0].friend_username = Sam"
]

It would be useful to see the function code which is failing.

Dataset in Collection which was created in Realm and transferred to MongoDB:

{
      _id : "606f48f6308c87387b529f17",
      _partition: `user=606870420b4920e213f004b9`, 
      userId: "606870420b4920e213f004b9",
      name: „Sam“,
      friends:
      {
        _id: "606f48f6308c87387b529f17",
        groupName: "New Group“,
        groupId: "6068707a29196eac831e64ab",
        friends_internal: [
          	{
            	 friend_status: "Open",
            	friend_userId:"606870420b4920e213f004b9",
            	friend_username:"jHerb",
          	},
          	{
            	friend_status: "Open",
            	friend_userId:"600bd66bd4f4f7a65e4965a5",
            	friend_username:“Robert“,
          	}
        ],
        created_by: "606870420b4920e213f004b9",
      }, 
    };

Mongo-Function:

exports = function(inputDocument) {

	const fullDocument = inputDocument.fullDocument;

  	console.log("1 … fullDocument.friends.name: " + fullDocument.friends.name);
  	console.log("2 … fullDocument.friends.friends_internal: " + fullDocument.friends.friends_internal);
  	console.log("3 … fullDocument.friends.friends_internal  0: " + fullDocument.friends.friends_internal[0]);

}

The following output I get in the Logs within MongoDB Realm:

	fullDocument.friends.name … result: „Sam“
	fullDocument.friends.friends_internal … result: undefined
	fullDocument.friends.friends_internal[0] … result: undefined

Your document + function + log output don’t match up. There is no friends.name in your document and so in my test, the first console.log output rightly shows as being undefined, but the next 2 show that the data is there:

Logs:
[
  "1 … fullDocument.friends.name: undefined",
  "2 … fullDocument.friends.friends_internal: [object Object],[object Object]",
  "3 … fullDocument.friends.friends_internal  0: [object Object]"
]

Sticking with your document, but updating the function, I get this…

db.User.insert(
    {
        _partition: "user=606870420b4920e213f004b9",
        userId: "606870420b4920e213f004b9",
        name: "Sam",
        friends:
        {
            _id: "606f48f6308c87387b529f17",
            groupName: "New Group",
            groupId: "6068707a29196eac831e64ab",
            friends_internal: [
                {
                    friend_status: "Open",
                    friend_userId:"606870420b4920e213f004b9",
                    friend_username:"jHerb",
                },
                {
                    friend_status: "Open",
                    friend_userId:"600bd66bd4f4f7a65e4965a5",
                    friend_username:"Robert",
                }
            ],
            created_by: "606870420b4920e213f004b9",
        }
    }
)
exports = function(inputDocument) {
    const fullDocument = inputDocument.fullDocument;
    // console.log("1 … fullDocument.friends.name: " + fullDocument.friends.name);
    console.log("2 … fullDocument.friends.friends_internal: " + fullDocument.friends.friends_internal);
    console.log("3 … fullDocument.friends.friends_internal[0]: " + fullDocument.friends.friends_internal[0]);
    console.log("4 … fullDocument.friends.friends_internal[0].friend_username: " + fullDocument.friends.friends_internal[0].friend_username);
}
Logs:
[
  "2 … fullDocument.friends.friends_internal: [object Object],[object Object]",
  "3 … fullDocument.friends.friends_internal[0]: [object Object]",
  "4 … fullDocument.friends.friends_internal[0].friend_username: jHerb"
]

I’m not sure what the mismatch is – are you sharing the actual document + function + log output or an edited version?

Hi again,
sorry for the confusion, I “manipulated”, means adapted the field name a little bit and have forgotten to do it on all places.
I had again a try on it but without any success…

Enclosed you can see the original Mongo-function, Document in the Collection and the log output I have.

MongoDB Function:

MongoDB Collection “document” I want to work within the MongoDB Function:
image

Log output when I run the function:
image

As you can see in the Log-Output, it looks like that the embedded object in the array, and in general the whole array “user_replies” is not accessible (present) via FullDocument.

Hope that helps and you can give me a hint how to go on!
Thanks in advance and BR
Dominik

Odd, I’ve not recreated your exact schema, but I’ve included the bits you’re trying to access and it seems to work fine:


exports = function(inputDocument) {
    const fullDocument = inputDocument.fullDocument;
    console.log("1 … fullDocument.param_eventObject.name: " + fullDocument.param_eventObject.name);
    console.log("2 … fullDocument.param_eventObject.user_replies: " + fullDocument.param_eventObject.user_replies);
    console.log("3 … fullDocument.param_eventObject.user_replies[0]: " + fullDocument.param_eventObject.user_replies[0]);
    console.log("4 … fullDocument.param_eventObject.user_replies[0].friend_username " + fullDocument.param_eventObject.user_replies[0].friend_username);
}
db.User.insert(
    {
        _partition: "user=606870420b4920e213f004b9",
        userId: "606870420b4920e213f004b9",
        name: "Sam",
        param_eventObject:
        {
            _id: ObjectId("606f48f6308c87387b529f17"),
            groupName: "New Group",
            groupId: "6068707a29196eac831e64ab",
            user_replies: [
                {
                    friend_status: "Open",
                    friend_userId:"606870420b4920e213f004b9",
                    friend_username:"jHerb",
                },
                {
                    friend_status: "Open",
                    friend_userId:"600bd66bd4f4f7a65e4965a5",
                    friend_username:"Robert",
                }
            ],
            created_by: "606870420b4920e213f004b9",
        }
    }
)
Logs:
[
  "1 … fullDocument.param_eventObject.name: undefined",
  "2 … fullDocument.param_eventObject.user_replies: [object Object],[object Object]",
  "3 … fullDocument.param_eventObject.user_replies[0]: [object Object]",
  "4 … fullDocument.param_eventObject.user_replies[0].friend_username jHerb"
]

Is this a new document being inserted or an existing one being updated?

Are you certain that user_replies is there when the document is inserted, and not added as part of a later update?

How is the document being written to the collection (e.g. from your app, or via MongoDB Realm Sync?)

What happens if you try inserting this document through the mongo shell?

The new document is being created in the Realm application and yes the document has the full information in, including the user_replies array when it will be inserted into the collection in the Realm, as you also can see in the screenshot from MongoDB Compass as well.

After creation of the document it will be synced to MongoDB where the function is getting started via a Trigger (start function at every insert in the collection).

To manually insert the document via MongoShell, I haven’t tried so far.

That’s strange for me, I really do not know how to go on with that topic.
Any other suggestions or ideas?

BR

I’d suggest cloning one of your docs from the mongo CLI and see whether the function works…

db.User.insertOne(doc)

(you can also clone a document from the Atlas UI).

Also, try adding this to your function and see what’s returned when cloning a document and when a new document is synced from Realm (I’m wondering whether Sync might insert the doc then update it with the embedded objects.)

console.log("1 … fullDocument.param_eventObject: " + JSON.stringify(fullDocument.param_eventObject));

I just did a test and confirmed that the EmbeddedObject was included in the insert when my Object was synced from my mobile app.

It would be good to confirm that this data is only being inserted (and not updated unexpectedly). Make sure that you trigger is active for updates as well as inserts and add this to the top of your trigger function:

  if (inputDocument.operationType != "insert") {
    console.log(`${inputDocument.operationType} event – currently ignored.`);
    return;
  }

Hi again,

I doublechecked it now, that it’s really inserted and NOT updated, see the screenshots below:

Function:

LOG:

Trigger-settings:

Unfortunately as you can see it’s really an INSERT, not an update.
But the user_replies is missing in the console.log(JSON.stringify(fullDocument.param_eventObject)) … but I really do not understand why. Nothing is updated or anything else after the document is inserted to the collection.

BR

What happens when you manually insert/clone a document?

Cloning the object in MongoDB Compass leads to a at least first success :slight_smile: … the user_replies array is in now but the question for me now is: WHY?

Log:

FULL-Log in Text:

Logs:

[ "inputDocument.operationType: insert", "1 … fullDocument.param_eventObject: {\"_id\":\"60c7704bd3ff3518615c9439\",\"calendarId\":\"6068707a29196eac831e64ab\",\"modified_by\":\"606870420b4920e213f004b9\",\"name\":\"My TestEVENT 1245678\",\"status\":\"Open\",\"user_replies\":[{\"reply_created_at\":\"2021-06-14T15:05:10.000Z\",\"reply_created_by\":\"jelldo90\",\"reply_modified_at\":\"2021-06-14T15:05:10.000Z\",\"reply_modified_by\":\"jelldo90\",\"reply_status\":\"Open\",\"reply_userId\":\"606870420b4920e213f004b9\",\"reply_username\":\"jelldo90\"},{\"reply_created_at\":\"2021-06-14T15:05:10.000Z\",\"r", "FullDocument.param_EventObject User_Replies: My TestEVENT 1245678", "FullDocument.param_EventObject User_Replies: [object Object],[object Object]", "FullDocument.param_EventObject User_Replies STELLE 0: [object Object]" ]

See Function. See Trigger.

Thanks at least for the first step in the right direction :slight_smile:

But what can be the reason behind now?
BR

Could you share the code that creates the Object and stores in it Realm?

Sorry for the late response.

After cloning the document within MongoDB, as I have described in the previous answer, the missing “user_replies” object was in.
So the creation of the document (including the embedded object “user_replies”) in Realm itself couldn’t be the problem in my point of view, right?

I also checked the original document and the cloned one, if there are any differences … but unfortunately it looks totally the same, in terms of content and datatypes as well.

So I was guessing in the direction of a time-related problem. Maybe that the document is not getting fully loaded when the trigger is starting the function … would that be possible?

I think that the most likely cause is going to be connected to how the Object is created in the client app. Can you share that client-side code (if need be, simplified)?

I will try to explain via a minimized code snippet:

Function which will be triggered via button on a screen for creation of a new entry in my collection and in collection of others (later via trigger and MongoDB function) as well.
At the call of the function I send the appropriate parameters, like the name (param_name) and the user_replies array (via param_UserReplyArray). This array I’m creating before triggering the function, this looks like:

const param_UserReplyArray = [{
        reply_status: "Open", 
        reply_created_at: Date(),
        reply_created_by: userdata[0]._id,
        reply_modified_at: Date(),
        reply_modified_by: userdata[0]._id,
        reply_userId: userdata[0]._id, 
        reply_username: userdata[0].userName}];

Function which is triggered by button as mentioned above:

const j_Event_Create = ({param_name, param_UserReplyArray}) => {

    const userRealm = realmRef.current;

    const objectID_event = new ObjectId();

    const object_new =
    {
      _id: objectID_event,
      name: param_name ,
      status: "Open",
      user_replies: param_UserReplyArray,
      modified_by: user.id,             
    };
    
    // Creation of the local Realm entry for myself
    userRealm.write(() => {

      const syncUser = userRealm.objects("User");
      syncUser[0].calendar.[0].event.push(object_new); 
    });


  // Creation of entries for other guys trough function „CreateEntryInForeignCollection_Create“

 CreateEntryInForeignCollection_Create({
    param_event_Object: object_new 
  });
};

Function „CreateEntryInForeignCollection_Create“ which will be triggered for creation of entry in other (foreign) collections:

const CreateEntryInForeignCollection_Create = ({param_event_Object}) => {

    const ActivityQueueRealm = realmRef.current;

    ActivityQueueRealm.write(() => {

      const Foreignentry_New = {
        _id : new ObjectId(),
        _partition: `user=${user.id}`, 
        userId: user.id, 
        param_eventObject: param_event_Object,
        modified_by: user.id,    
      };

      ActivityQueueRealm.create("Activity_Queue",Foreignentry_New);

    });
  };

And with this entry I want to work within the function in MongoDB, means this created entry is the one I’m receiving in my MongoDB function trough the trigger.

Hope that helps.

BR Dominik

Hi @Dominik_Jell, I haven’t used Realm from JavaScript, but I did take a look at how embedded objects work… https://docs.mongodb.com/realm/sdk/node/data-types/embedded-objects/

Have you tried including embedded: true in each of your objects that aren’t at the top-level of your Realm object?

Hi Andrew,

thank you for information concerning the docs. I have already checked the docs due to embedded objects and it looks fine.

Embedded is set to true in all the embedded objects where it’s relevant, so this should be ok in my point of view.

BR Dominik