Tengo una relación que se ve así:
model Fighter { id Int @id @default(autoincrement()) name String image String? description String? battles Battle[] votes Vote[] } model Vote { Fighter Fighter @relation(fields: [fighterId], references: [id]) fighterId Int Battle Battle @relation(fields: [battleId], references: [id]) battleId Int count Int @default(0) @@id([fighterId, battleId]) } model Battle { id Int @id @default(autoincrement()) slug String @unique name String fighters Fighter[] votes Vote[] }
Una batalla tiene varios luchadores y hay un modelo de votación que cuenta el voto de cada luchador en una batalla. Quiero recuperar una batalla, incluir a los luchadores e incluir el voto de cada luchador. Hice esta consulta:
prisma.battle.findMany({ take: count, skip: skip, include: { fighters: { include: { votes: { select: { count: true } } } } } });
Lo que resuelve aproximadamente mi problema porque en el resultado un luchador tiene una variedad de votos, como este:
{ "id": 2, "slug": "Random-1", "name": "Random 1", "fighters": [ { "id": 3, "name": "1 dragon", "image": null, "votes": [ { "count": 3 } ] }, { "id": 6, "name": "1 hero", "image": null, "votes": [ { "count": 1 } ] } ] }
Pero lo que me gustaría es, en el mejor de los casos, pero dudo que sea posible:
{ "id": 6, "name": "1 hero", "image": null, "votes": 1 }
Tener el conteo de votos directamente en mi objeto luchador o al menos, solo un voto en el objeto luchador
{ "id": 6, "name": "1 hero", "image": null, "votes": { "count": 1 } }
No sé si mi problema es un problema de esquema entre mis modelos o si puedo resolverlo con las consultas de Prisma. Traté de usar la API de include
y select
de Prisma pero no pude resolver esto. ¿Alguien tiene una idea sobre esto?
Podría usar la cláusula _count que le permitiría tener una respuesta similar a la que espera.
Aquí está la consulta:
import { PrismaClient } from '@prisma/client'; const prisma = new PrismaClient(); async function main() { await prisma.battle.create({ data: { name: 'Battle of the Vowels', slug: 'battle-of-the-vowels', fighters: { create: { name: 'Kabal', description: 'Kabal is a fictional character in the Star Wars franchise. He is a member of the Jedi Order.', image: 'https://vignette.wikia.nocookie.net/starwars/images/7/7e/Kabal_HS-SWE.png/revision/latest?cb=20170504075154', votes: { create: { battleId: 1, }, }, }, }, }, }); // // Updated Query // const battle = await prisma.battle.findMany({ // take: count, // skip: skip, include: { fighters: { include: { _count: { select: { votes: true, }, }, }, }, }, }); console.log(JSON.stringify(battle, null, 2)); } main() .catch((e) => { throw e; }) .finally(async () => { await prisma.$disconnect(); });
Aquí está la respuesta de muestra:
[ { "id": 1, "slug": "battle-of-the-vowels", "name": "Battle of the Vowels", "fighters": [ { "id": 1, "name": "Kabal", "image": "https://vignette.wikia.nocookie.net/starwars/images/7/7e/Kabal_HS-SWE.png/revision/latest?cb=20170504075154", "description": "Kabal is a fictional character in the Star Wars franchise. He is a member of the Jedi Order.", "_count": { "votes": 1 } } ] } ]
Referencia para usar la cláusula _count: _count prisma