Help with Database Schema for Dating Type App - Using User Table for Everything?

Hi!

We’re working to move a poorly designed Dating type app from a WordPress/MySQL backend to Parse with a MongoDB NoSQL database. The previous app won’t scale and just wasn’t built well.

Before we get too far into the development, looking for advice or best practices for setting up the database schema for ease, indexing, queries, etc.

Most everything in the app is related to a user (their login (email, password), their username for the dating app, birthdate, preferences, what they are looking for (traits, likes, dislikes), their profile pics, and even their geo location so other users can filter and see users around them.

A suggested schema is below, where literally all of this is in the one user collection. This is neat and tidy, but is there any downside to this? Would there be any reason that authentication details and then user profile details should be separate and linked by their uniqueID’s? Same with location, where we store their geo coordinates, which will change often as they move around - is it ok to also have that in the user document or should another collection be creates solely for tracking geopoints? There are also one to many/relational type data items to store as well, such as who this user has blocked, who they have marked as liked, etc. Assuming these types of things can be stored in arrays, but again, is it ok to have all of this under the user collection, or should things like ‘liked’ and ‘blocked’ be separate collections? It’s sometimes hard to get your head around the differences between SQL and NoSQL where these types of data would need to be separate relational tables, but in NoSQL they could theoretically all exist in one collection.

Thanks for any advice on this, we’ve seen it done a variety of ways and would love insight on the pros and cons.

Finally, if anyone sees any red flags with using MongoDB for this, i know NoSQL can be tricky with queries, we’ll need to be able to filter users by location, presence (on/offline), and traits/characteristics, including ranges (like if a user wants to see everyone around them that is online, between ages of 18 and 45), etc.

Thank you!

A rough idea of the schema with everything under the user collection:

{
“_id”: ObjectId(“unique user ID”),
“username”: “user123”,
“email”: “[email protected]”,
“password”: “hashed_password”,
“birthdate”: ISODate(“1990-01-01T00:00:00Z”),
“gender”: “male”,
“location”: {
“type”: “Point”,
“coordinates”: [longitude, latitude]
},
“photos”: [“url1”, “url2”],
“bio”: “A little bit about me…”,
“interests”: [“hiking”, “cooking”, “movies”],
“attributes”: {
“height”: 175, // in cm
“education”: “Ph.D.”,
“occupation”: “Software Engineer”,
// Other attributes…
},
“likes”: [“user456”, “user789”],
“dislikes”: [“user234”],
“matches”: [“user987”],
“blockedUsers”: [“user567”],
“createdAt”: ISODate(“2023-10-18T12:00:00Z”),
“updatedAt”: ISODate(“2023-10-18T15:30:00Z”)
}

This is the best thing for NoSQL!

If your app primarily involves User-based queries, you should consider the costs associated with frequent querying. If you are fetching need access to all information, such as likes and location, the Embedded design pattern is a good choice for your database queries. This pattern allows you to retrieve or set all of this data with a single query.

However, it’s important to note that this pattern is referred to as the ‘Embedded design pattern.’ There are various patterns available, and you can choose the one that best suits your needs.

For example:

db.blog.findOne()
{
  _id: ObjectId("649a137d51953aa117e8d6c3"),
  title: 'aggregate',
  comments: [ ======> REFERENCED
    ObjectId("649a13a051953aa117e8d6c4"),
    ObjectId("649a13a051953aa117e8d6c5"),
    ObjectId("649a13a751953aa117e8d6c5")
  ],
  embeddedComment: { =========> EMBEDDED
    _id: ObjectId("649a13a051953aa117e8d6c4"),
    comment: 'hmmm, ilgi çekici'
  }
}

The choice of pattern depends on the specific requirements of your app.

If you had been developing an e-commerce application, I would have recommend using the ‘reference design pattern.’

For now, your app seems to be in good shape.