MongoDB one-way embedding (one-way, one-sided) relations
See original GitHub issueProblem
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:
- Created a year ago
- Reactions:14
- Comments:10 (3 by maintainers)
Top GitHub Comments
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 🙏
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).
Having difficulty using prisma on top of existing project. In the example above.
bar
is easy to implement, but there is no way to populatebazz
becauseBazz
collection has no idea aboutfooSchema
.