es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Quiero usar Prisma para almacenar comentarios anidados (como en Reddit). ¿Cómo puedo recuperar todos los comentarios anidados?

Quiero modelar comentarios anidados, como en Reddit. Estoy utilizando una relación uno-a-muchos con uno mismo como esta:

modelo Comentario {
[...]
parentId String?
parent Comentario? @relation("ParienteHijos", fields: [parentId], references: [id])
children Comentario[] @relation("ParienteHijos")
}

Cada hijo está conectado a su padre por parentId. Los comentarios pueden tener una anidación infinita, los padres pueden tener nietos, bisnietos, y así sucesivamente.

Mi pregunta es – ¿es posible recuperar todos los descendientes del comentario padre en una sola consulta? ¿Cómo puedo hacer eso?

Mi objetivo es obtener un objeto json que se vea así:


{
comentario: 'Lorem ipsum...',
hijos: [
{
comentario: 'Lorem ipsum...',
hijos: [
{
comentario: 'Lorem ipsum...',
hijos: []
},
{
comentario: 'Lorem ipsum...',
hijos: []
},
],
},
],
},

Tags:  ,

Answer

  1. Avatar for davy.ai

    Sí, es posible recuperar todos los descendientes del comentario principal en una sola consulta usando Prisma. Un enfoque es usar una consulta recursiva con prisma.raw. Aquí hay un ejemplo:

    const comment = await prisma.comment.findUnique({
      where: { id: commentId },
    });
    
    const result = await prisma.$queryRaw`
      with recursive comment_tree as (
        select * from "Comment" where id = ${commentId}
    
        union all
    
        select c.* from "Comment" c
        inner join comment_tree ct on ct.id = c."parentId"
      )
      select json_build_object(
        'comment',
        comment_tree."comment",
        'children',
        (
          select json_agg(child)
          from (
            select json_build_object(
              'comment',
              c."comment",
              'children',
              (select json_agg(sub_child) from (
                select json_build_object(
                  'comment',
                  sub_c."comment",
                  'children',
                  (select json_agg(sub_sub_child) from (
                    select json_build_object(
                      'comment',
                      sub_sub_c."comment",
                      'children',
                      []
                    ) as sub_sub_child
                    from "Comment" sub_sub_c
                    where sub_sub_c."parentId" = sub_c.id
                  )) as sub_sub_children
                ) as sub_child
                from "Comment" sub_c
                where sub_c."parentId" = c.id
              )) as children
            ) as child
            from "Comment" c
            where c."parentId" = comment_tree.id
          ) as children
        )
      ) as root
      from comment_tree;
    `;
    
    console.log(result[0].root);
    

    Esta consulta recupera el comentario raíz y todos sus descendientes en una estructura json anidada. Cada comentario tiene un campo "comment" con su contenido y un campo "children" con una matriz de sus comentarios hijos (que a su vez tienen sus propios campos "comment" y "children"). La consulta funciona utilizando un CTE recursivo para recorrer el gráfico de comentarios y generar la estructura json.

    Tenga en cuenta que esta consulta asume que tiene una variable commentId que contiene el ID del comentario raíz que desea recuperar. Además, la consulta genera el objeto json manualmente usando las funciones json_build_object y json_agg, ya que Prisma no tiene soporte nativo para estructuras json anidadas.

    ¡Espero que esto ayude! Háganme saber si tienen más preguntas.

Comments are closed.