Rethinking my MongoDB User document structure

I’m rethinking how I want to structure some data which is currently being stored in the Users Collection. Previously, my server would receive messages, find the user document with the right profile.website field, and push an item into the profile.siteMessages array:

{
  "_id": "hr9ck5Fis5YuvqCqP",
  "profile": {
    "website": "localhost",
    "siteMessages": [
         {
            "text": "sddsd",
            "createdAt": 1482001227204
         },
     ]
  }
}

Id like to change the structure to look something like the following. Instead of storing all messages, of which multiple messages could come from the same user, in a top level array in profile, I would have a profile.siteVisitors field which contains a visitorId and then the array of messages:

{
  "_id": "dgfsdfdfsdf",
  "emails": [
    {
      "address": "user2@test.com",
      "verified": false
    }
  ],
  "profile": {
    "website": "localhost",
    "siteVisitors:" [
      	{
      	  "visitorId": "74585242",
          "messages": [
            {
              "text": "A string",
              "createdAt": 1482001260853
            },
            {
              "text": "Another string",
              "createdAt": 1482001260854
            }
          ]
      	},
        {
          "visitorId": "76672242",
          "messages": [
            {
              "text": "A string",
              "createdAt": 1482001260855
            }
          ]
        }
     ]
  }
}

I have two questions:

  1. What is wrong with this structure? How would you rather structure it and why?
  2. Keeping with the structure shown above, how would I query for and update the profile.siteVisitiors.messages array? Currently I query and update the Collection using something like the following:
Meteor.users.update({'profile.website': url}, {$push: {'profile.siteMessages': msgItem}}, function(err) {
	if (err) {
	    console.log('whoops!' + err)
	} else {
		//success					
	}
});

How would I update the newly structured messages array? I would need to match a User documents profile.website field, match an visitorId in the profile.siteVisitors array, and then push a new element into the messages array, but I’m not sure how this would look as a MongoDB query.

There are two main concepts when it comes to data storage in MongoDB. The right blend of the two gives you the maximum performance.

  1. Embedding data. You have a user profile and want to store some details about the user, 2-3 addresses, the last comment of the user etc.
  2. Referencing data. I feel this is the case you should focus on in your situation.

You would use a new collection for Messages, indexed by user ID or profile ID, whichever you want to use as reference to find the messages.

ok … I don’t know why all these old messages are popping up in the feed but I just replied to a problem someone had 7 years ago. I hope @orbyt moved on in life those many years back and didn’t wait for a reply… :joy:

@paulishca

There is In Progress reorganizing of uncategorized topics, and answering old topics, because for many topics, now we have answers.

@orbyt

Related to schema, newest cool stuff is schema driven UI: