question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

MongoDB one-way embedding (one-way, one-sided) relations

See original GitHub issue

Problem

When using the mongoDB I find it problematic that many-to-many relations have to be stored on “both sides”.

An example use case:

model Post {
  id      String   @id
  users User[]   @relation(fields: [userIds], references: [id])
  userIds String[]
}

model User {
  id           String   @id
  likes        Post[]   @relation(references: [id], fields: [likedPostIds])
  likedPostIds String[]
}

This simple data model would allow me to use prisma’s nice Fluent API, and do things like User.likes(). However, this is not scalable at all, if a Post has a million likes, the userIds array is going to be huge.

Suggested solution

Ideally, I would like to have the flexibility to decide for myself how the data is going to be structured. For my use case, I will never need to follow the relation from Post=>User, only User=>Post.

I wish the formatter would allow one-way relations, that way it could be as simple as:

model Post {
  id String @id
}

model User {
  id           String   @id
  likes        Post[]   @relation(references: [id], fields: [likedPostIds])
  likedPostIds String[]
}

or (with the back relation):

model Post {
  id String @id
  users User[]
}

model User {
  id           String   @id
  likes        Post[]   @relation(references: [id], fields: [likedPostIds])
  likedPostIds String[]
}

Alternatives

The only alternative is to have a very granular “join table”, such as this:

model Post {
  id String @id @map("_id")

  LikesByUser LikesByUser[]
}

model LikesByUser {
  userId String
  post   Post   @relation(fields: [postId], references: [id])
  postId String
  User   User   @relation(fields: [userId], references: [id])

  @@id([userId, postId])
}

model User {
  id          String        @id @map("_id")
  LikesByUser LikesByUser[]
}

Other than inconvenience, the downside of doing this is that it isn’t very storage efficient.

Issue Analytics

  • State:open
  • Created a year ago
  • Reactions:14
  • Comments:10 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
dimaipcommented, Jul 5, 2022

Here’s a good explanation why two-way embeds won’t work well for large sets of items: https://learnmongodbthehardway.com/schema/schemabasics/#one-way-embedding

So yes, it’s a rather big gap in terms of data modelling for Mongo, so would be awesome if this issue could be prioritised 🙏

For my use case, I will never need to follow the relation from Post=>User, only User=>Post.

Actually the relation can be followed both ways just fine in a performant way thanks to Mongo’s query engine (given you have an index on that field).

1reaction
MinSomaicommented, Nov 11, 2022
 const fooSchema = new mongoose.Schema({
  bar: { type: mongoose.Schema.ObjectId, ref: 'Bar required: true },
  bazz: [{ type: mongoose.Schema.ObjectId, ref: 'Bazz }],
});

Having difficulty using prisma on top of existing project. In the example above. bar is easy to implement, but there is no way to populate bazz because Bazz collection has no idea about fooSchema.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Model One-to-One Relationships with Embedded Documents
This page describes a data model that uses embedded documents to describe a one-to-one relationship between connected data. Embedding connected data in a...
Read more >
Relations in MongoDB: One-to-One, One-to-Many ...
In MongoDB, one-to-one, one-to-many, and many-to-many relations can be implemented in two ways: Using embedded documents; Using the reference of documents ...
Read more >
17. Scenario when to use One to Many Relationship with ...
In this video we will see the scenarios when to use the one to many relationship with embedded documents in the best way...
Read more >
One to one relation in mongo database with id - YouTube
In # MongoDB database, we need to link documents with each other for referencing purpose. this can be done via embedded documents or...
Read more >
Schema Basics
A One to One Relational Example. The 1:1 relationship can be modeled in two ways using MongoDB. The first is to embed the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found