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 connector: Model discriminators / single table inheritence

See original GitHub issue

Problem

A common use case is to store different shapes of a document in the same collection and use a discriminator column to tell them apart. Raw mongodb JSON example data follows:

{
  "_id": "71ed6b0f-e08e-4bad-acf2-e02653aad1aa",
  "body": "This is my second post.",
  "type": "post",
  "slug": "prisma-is-type-safe-mongodb-client",
  "title": "Prisma is a type-safe MongoDB client"
}

and

{
  "_id": "7aa65cb4-e4b4-4a82-a26e-549d0bb5e3a7",
  "postId": "71ed6b0f-e08e-4bad-acf2-e02653aad1aa",
  "type": "comment",
  "comment": "Great post!"
}

And then, these two documents can be described as follows in the Prisma Schema:

model Post {
  id         String    @id @default(uuid()) @map("_id")
  type       String    @default("post")
  slug       String    @unique
  title      String
  body       String
  comments   Comment[]

  @@map("someCollection")
}

model Comment {
  id         String    @id @default(uuid()) @map("_id")
  type       String    @default("comment")
  post       Post      @relation(fields: [postId], references: [id])
  postId     String
  comment    String

  @@map("someCollection")
}

With this, most things work, except if you need to fetch a list of documents directly where the criteria overlaps between the variant types:

PrismaClientUnknownRequestError2 [PrismaClientUnknownRequestError]: 
Invalid `prisma.post.findMany()` invocation:


  Attempted to serialize scalar 'null' with incompatible type 'String'

Workaround

A work around is to add a filter to the findMany query to only return the documents matching the desired discriminator column:

await prisma.post.findMany({
  where: { type: "post" },
  include: {
    comments: true,
  },
})

Suggested solution

Add something like @discriminator to fields and then use it’s value whenever doing lookups for a model.

model Post {
  id         String    @id @default(uuid()) @map("_id")
  type       String    @default("post") @discriminator
  slug       String    @unique
  title      String
  body       String
  comments   Comment[]

  @@map("someCollection")
}

and so calling

await prisma.post.findMany({
  include: {
    comments: true,
  },
})

will work.

Additional context

More than one discriminator could also be very useful.

Perhaps the @discriminator could work like this: @discriminator("value") and automatically include @ignore on the field, maybe?

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:5
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
matthewmuellercommented, Apr 22, 2021
0reactions
SagnikPradhancommented, Apr 14, 2022

Any updates on this issue?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Inheritance — Mongoid Manual 8.0 - MongoDB
Mongoid supports inheritance in both top level and embedded documents. ... There are two ways to change the discriminator key, on the class...
Read more >
Mongoose v6.8.1: Discriminators
Discriminators are a schema inheritance mechanism. They enable you to have multiple models with overlapping schemas on top of the same underlying MongoDB...
Read more >
Mongoose Discriminator: An easy way to inherit schema ...
I accessed the environment variables and got the development and production URI for the MongoDB connection. The mongoose connect method ...
Read more >
Mongodb Polymorphic relation and Single Table inheritance ...
This VIDEO SPECIFICALLY COVERS POLYMORPHIC ASSOCIATION AND SINGLE TABLE INHERITANCE using mongoose discriminator.mo...
Read more >
NestJS #45 - MongoDB & Mongoose | Discriminators | (Hindi)
The Discriminators are a Schema Inheritance Mechanism. They allow us to have multiple models inheriting common fields from a parent schema, ...
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