Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB schema strategy for users joining a group [closed]

Imagine Facebook's group feature, using MongoDB. What would be the best way to structure the data?

Main operations on this data will be find users who belong to the group and determine if user X is a member of the group.

One option would be to have an array of strings in the Group document.

{
  name: "Pets United",
  members: [
    "iuahsdfuhasdfasdf",
    "qwefqwefqwefqweff",
    "ioeroigkergnknmkm"
  ]
}

Another would be to have a membership array of Group id's in the User document.

{ 
  firstName: "Sergio",
  age: 27,
  groups: [
    "iuahsdfuhasdfasdf",
    "qwefqwefqwefqweff",
    "ioeroigkergnknmkm"
  ]
}

Which one do you guys think is better if I expect a group to have thousands of users?

like image 500
Sergio Tapia Avatar asked Jan 09 '16 01:01

Sergio Tapia


People also ask

What is polymorphic schema in MongoDB?

MongoDB is sometimes referred to as a “schemaless” database, meaning that it does not enforce a particular structure on documents in a collection. It is perfectly legal (though of questionable utility) to store every object in your application in the same collection, regardless of its structure.

Does MongoDB have a fixed schema?

Data in MongoDB has a flexible schema. Collections do not enforce document structure by default. This flexibility gives you data-modeling choices to match your application and its performance requirements.

What is schema used in MongoDB?

A schema is a JSON object that defines the the structure and contents of your data. You can use App Services's BSON schemas, which extend the JSON Schema standard, to define your application's data model and validate documents whenever they're created, changed, or deleted.


1 Answers

TL;DR It's a trade-off between things like managing documents and querying those documents.

Keep in mind MongoDB documents have a size limit of 16MB (which will take forever to reach using an array containing strings, but still). I would probably do the relationship "person belongs to group", rather than "group contains people":

{ 
  firstName: "Sergio",
  age: 27,
  groups: [
    "iuahsdfuhasdfasdf",
    "qwefqwefqwefqweff",
    "ioeroigkergnknmkm"
  ]
}

The likelihood of a group containing thousands of members is more likely than a person belonging to thousands of groups, so if document size limit is a concern at all (which it probably won't be, but regardless), I would go with the "people to groups relationship" as you suggested.

Also keep in mind how you will query for data. In your first example ("group contains people"), to display the users in a group page, you will need to do:

people.find({ _id: { $in: group.members } })

Whereas to query the other way around:

people.find({ $where: 'this.groups.indexOf(group) > -1' })

Those are simply examples to illustrate ways of doing it (there may be others).

like image 179
Josh Beam Avatar answered Sep 26 '22 18:09

Josh Beam