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.

Obtener acceso al “elemento actual” al recorrer una matriz de mongoDB (mongoose)

Tengo un modelo mongoose para una “publicación similar a una red social” (llamado PostModel) que tiene este esquema:

{
  caption: String,
  comments: [
    {
      comment: String,
      // básicamente es un array para almacenar a todos aquellos a quienes les gustó el comentario
      likedBy: [...] // array de referencias a un modelo diferente
    },
    ... // hay más objetos de comentario como este
  ]
}

Simplemente quiero saber el número de me gusta que ha recibido cada comentario al consultar una publicación. Esto no debería ser tan molesto ni difícil como lo es. He pasado más de 4 horas en esto.

Lo que intenté hasta ahora:

Intento 1:

PostModel.findById(postId, {
  "comments.likes": { $size: "$comment.likedBy" } // da el número de comentarios en lugar del número de me gusta en el comentario
})

Intento 2:

PostModel.findById(postId, {
  "comments.likes": { $size: "$likedBy" } // da un error "likedBy no está definido"
})

Intento 3:

PostModel.findById(postId, {
  "comments.likes": { $size: "$comments.$likedBy" } // da un error "Los nombres de campo de FieldPath no pueden comenzar con '$'. Considere usar $getField o $setField"
})

Intento 4:

PostModel.findById(postId, {
  "comments.likes": { $size: "$comments.$.likedBy" } // da un error "Los nombres de campo de FieldPath no pueden comenzar con '$'. Considere usar $getField o $setField"
})

Básicamente quiero acceder al “elemento actual” en este recorrido de array similar a “forEach”. Por ejemplo:

const a = [{likes: ["x", "y"]}, {likes: ["a", "b"]}, {likes: []}];
a.forEach((element, index) => {
  console.log(element.likes.length) // esto es lo que quiero pero para mongoDB
})
// resultado: 2 2 0

He buscado por todas partes pero no pude encontrar una solución incluso después de buscar durante 4 horas. Cualquier cosa que me guíe en la dirección correcta sería útil.

No quiero cargar todo el array de comentarios en la memoria solo para obtener las longitudes de los arrays anidados likedBy. De lo contrario, esto ni siquiera sería un problema.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para resolver el problema de obtener el número de “likes” para cada comentario en la publicación, se puede hacer uso del marco de agregación de MongoDB. El primer paso sería desenrollar la matriz de comentarios para separar cada comentario en su propio documento, luego agrupar por comentario y usar el operador $size para contar el número de “likes” para cada comentario. Aquí tienes un ejemplo de cómo se puede hacer:

    PostModel.aggregate([
      { $match: { _id: postId } },
      { $unwind: "$comments" },
      { $group: { _id: "$comments", likes: { $sum: { $size: "$comments.likedBy" } } } }
    ])
    

    Esta consulta devolverá una matriz de documentos, donde cada documento representa un comentario y el número total de “likes” para ese comentario. El campo _id contendrá el objeto de comentario y el campo likes contendrá el número de “likes” para ese comentario.

    Ten en cuenta que este enfoque puede no ser eficiente si tienes un gran número de comentarios o si las matrices “likedBy” son muy grandes. En ese caso, es posible que necesites considerar optimizar tu esquema o utilizar una tecnología de base de datos diferente.

Comments are closed.