I have three table, artist, album and track. I want to query artist who have at least one song track.
Here is my graphql prisma schema. May I know how write the query?
generator client {
provider = "prisma-client-js"
binaryTargets = ["native", "linux-musl"]
}
generator typegraphql {
provider = "typegraphql-prisma"
emitTranspiledCode = true
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
model Artist {
id String @id @default(cuid())
name String @unique @db.VarChar(255)
bio String? @db.VarChar(1024)
profile_picture String @db.VarChar(512)
albums Album[]
tracks Track[]
active Boolean @default(true)
user User @relation(fields: [user_id], references: [id])
user_id String
created_at DateTime @default(now())
updated_at DateTime? @updatedAt
@@map("artists")
}
model Album {
id String @id @default(cuid())
title String @db.VarChar(255)
album_cover String @db.VarChar(512)
description String? @db.VarChar(5120)
released Int @default(1900)
artists Artist[]
genres Genre[]
tracks Track[]
active Boolean @default(true)
user User @relation(fields: [user_id], references: [id])
user_id String
created_at DateTime @default(now())
updated_at DateTime? @updatedAt
@@map("albums")
}
model Track {
id String @id @default(cuid())
title String @db.VarChar(255)
description String? @db.VarChar(5120)
lyric String? @db.LongText
mp3_url String @db.VarChar(1024)
youtube_url String @db.VarChar(1024)
band String? @db.VarChar(255)
duration Int @default(0)
artists Artist[]
album Album @relation(fields: [album_id], references: [id])
album_id String
songWriters SongWriter[]
active Boolean @default(true)
user User @relation(fields: [user_id], references: [id])
user_id String
created_at DateTime @default(now())
updated_at DateTime? @updatedAt
@@map("tracks")
}
Here is Resolver
import { Resolver, ArgsType, Field, Args, Query, Ctx, ObjectType,
Int } from "type-graphql";
import { Artist } from "@generated/type-graphql";
import { Context } from "../interfaces";
@ArgsType()
export class ArtistArgs {
@Field((type) => Int, { nullable: false })
page!: number;
@Field((type) => Int, { nullable: false })
take!: number;
}
@ObjectType()
export class ArtistResponse {
@Field(type => [Artist])
artists: Artist[] =[];
@Field((type) => Int, { nullable: false })
total!: number;
}
@Resolver()
class ArtistResolver {
//@Authorized("ADMIN")
@Query((returns) => ArtistResponse, { nullable: true })
async getArtists(@Ctx() { req, res, prisma }: Context, @Args()
{ page, take }: ArtistArgs): Promise<ArtistResponse | null> {
const artists = (await prisma.artist.findMany({
take: take,
skip: (page - 1) * take,
orderBy: [
{
name: "asc"
}
]
}));
const count = (await prisma.artist.count({
}));
return {artists: artists, total: count};
}
}
export default ArtistResolver;
This is like my answer in Prisma js ORM - how to filter for results that have entry in a related table (effectively JOIN)?
To get only Artist
s that have at least one Track
, you should use some and specify a condition that always return true for any related record that exists.
And if you want to your query includes related Track
s you must specify it in include property.
await prisma.artist.findMany({
where: {
tracks: {
some: {
id: { not: "" } // It always should be true.
},
},
},
// if you want to include related tracks in returned object:
include: {
tracks: true,
},
});