Получить доступ к «текущему элементу» при обходе массива MongoDB (mongoose)

#javascript #node.js #mongodb #mongoose #nosql

#javascript #node.js #mongodb #мангуст #nosql

Вопрос:

У меня есть модель мангуста для «публикации в социальных сетях» (называемая PostModel), которая имеет следующую схему:

 {
  caption: String,
  comments: [
    {
      comment: String,
      // basically an array to store all those who liked the comment
      likedBy: [...] // array of references to a different model
    },
    ... // more comment objects like this
  ]
}
 

Я просто хочу знать, сколько лайков получил каждый комментарий при запросе публикации. Это не должно быть так раздражающе и сложно, как есть на самом деле. Я потратил на это более 4 часов.

То, что я пробовал до сих пор:

Попытка 1:

 PostModel.findById(postId, {
  "comments.likes": { $size: "$comment.likedBy" } // gives the number of comments instead of the number of likes on the comment
})
 

Попытка 2:

 PostModel.findById(postId, {
  "comments.likes": { $size: "$likedBy" } // gives "likedBy not defined" error
})
 

Попытка 3:

 PostModel.findById(postId, {
  "comments.likes": { $size: "$comments.$likedBy" } // gives "FieldPath field names may not start with '

Попытка 4:

 PostModel.findById(postId, {
  "comments.likes": { $size: "$comments.$.likedBy" } // gives "FieldPath field names may not start with '

Я в основном хочу получить доступ к "текущему элементу" в этом "forEach", как обход массива. Например:

 const a = [{likes: ["x", "y"]}, {likes: ["a", "b"]}, {likes: []}];
a.forEach((element, index) => {
  console.log(element.likes.length) // this is what I want but for mongoDB
})
// output: 2 2 0
 

Я искал везде, но не мог найти решение даже после 4-часовых поисков. Было бы полезно все, что указывало бы мне хотя бы отдаленно на текущее направление.

Я не хочу загружать весь массив комментариев в память только для того, чтобы получить длины вложенных массивов likedBy. В противном случае это даже не было бы проблемой.


Ответ №1:

Если вы хотите получить общее количество лайков от всех comments , вы можете использовать оператор $reduce:

 {
    $project: {
        likes: {
            $reduce: {
                input: "$comments",
                initialValue: 0,
                in: { $add: [ "$value", { $size: "$this.likedBy" } ] }
            }
        }
    }
}
 

Игровая площадка Mongo

В качестве альтернативы вам может понадобиться $map, чтобы обогатить каждый комментарий количеством лайков:

 {
    $project: {
        comments: {
            $map: {
                input: "$comments",
                in: {
                    $mergeObjects: [
                        "$this",
                        { $numberOfLikes: { $size: "$this.likedBy" } }
                    ]
                }
            }
        }
    }
}
 

Игровая площадка Mongo

Комментарии:

1. ДА. Это действительно так. Я искал "$$this", "вещь оператора". На самом деле я не знал, что он существует, так что спасибо за это.

. Consider using $getField or $setField" error
})
Попытка 4:


Я в основном хочу получить доступ к "текущему элементу" в этом "forEach", как обход массива. Например:


Я искал везде, но не мог найти решение даже после 4-часовых поисков. Было бы полезно все, что указывало бы мне хотя бы отдаленно на текущее направление.

Я не хочу загружать весь массив комментариев в память только для того, чтобы получить длины вложенных массивов likedBy. В противном случае это даже не было бы проблемой.

Ответ №1:

Если вы хотите получить общее количество лайков от всех comments , вы можете использовать оператор $reduce:


Игровая площадка Mongo

В качестве альтернативы вам может понадобиться $map, чтобы обогатить каждый комментарий количеством лайков:


Игровая площадка Mongo

Комментарии:

1. ДА. Это действительно так. Я искал "$$this", "вещь оператора". На самом деле я не знал, что он существует, так что спасибо за это.

. Consider using $getField or $setField" error
})
Я в основном хочу получить доступ к «текущему элементу» в этом «forEach», как обход массива. Например:


Я искал везде, но не мог найти решение даже после 4-часовых поисков. Было бы полезно все, что указывало бы мне хотя бы отдаленно на текущее направление.

Я не хочу загружать весь массив комментариев в память только для того, чтобы получить длины вложенных массивов likedBy. В противном случае это даже не было бы проблемой.

Ответ №1:

Если вы хотите получить общее количество лайков от всех comments , вы можете использовать оператор $reduce:


Игровая площадка Mongo

В качестве альтернативы вам может понадобиться $map, чтобы обогатить каждый комментарий количеством лайков:


Игровая площадка Mongo

Комментарии:

1. ДА. Это действительно так. Я искал «$$this», «вещь оператора». На самом деле я не знал, что он существует, так что спасибо за это.

. Consider using $getField or $setField» error
})

Попытка 4:


Я в основном хочу получить доступ к «текущему элементу» в этом «forEach», как обход массива. Например:


Я искал везде, но не мог найти решение даже после 4-часовых поисков. Было бы полезно все, что указывало бы мне хотя бы отдаленно на текущее направление.

Я не хочу загружать весь массив комментариев в память только для того, чтобы получить длины вложенных массивов likedBy. В противном случае это даже не было бы проблемой.

Ответ №1:

Если вы хотите получить общее количество лайков от всех comments , вы можете использовать оператор $reduce:


Игровая площадка Mongo

В качестве альтернативы вам может понадобиться $map, чтобы обогатить каждый комментарий количеством лайков:


Игровая площадка Mongo

Комментарии:

1. ДА. Это действительно так. Я искал «$$this», «вещь оператора». На самом деле я не знал, что он существует, так что спасибо за это.