I Have a document like this :
{
"_id": {
"$oid": "64494e6a2f90fa940d5a406c"
},
"theme": "Harry Potter",
"date": {
"$date": "2023-04-26T22:00:00.000Z"
},
"quiz": [
{
"question": "Qui a une cicatrice sur le front ?",
"responses": [
{
"nbVote": 1,
"label": "Ron",
"isCorrect": false,
"_id": {
"$oid": "64494e6a2f90fa940d5a405a"
}
},
{
"nbVote": 0,
"label": "Hermione",
"isCorrect": false,
"_id": {
"$oid": "64494e6a2f90fa940d5a405b"
}
},
{
"nbVote": 0,
"label": "Malfoy",
"isCorrect": false,
"_id": {
"$oid": "64494e6a2f90fa940d5a405c"
}
},
{
"nbVote": 0,
"label": "Harry",
"isCorrect": true,
"_id": {
"$oid": "64494e6a2f90fa940d5a405d"
}
}
],
"_id": {
"$oid": "64494e6a2f90fa940d5a405e"
}
},
{
"question": "De quel maison fait partie Harry Potter ?",
"responses": [
{
"nbVote": 0,
"label": "Poufsouffle",
"isCorrect": false,
"_id": {
"$oid": "64494e6a2f90fa940d5a4063"
}
},
{
"nbVote": 0,
"label": "Serpentard",
"isCorrect": false,
"_id": {
"$oid": "64494e6a2f90fa940d5a4064"
}
},
{
"nbVote": 0,
"label": "Serdaigle",
"isCorrect": false,
"_id": {
"$oid": "64494e6a2f90fa940d5a4065"
}
},
{
"nbVote": 1,
"label": "Gryffondor",
"isCorrect": true,
"_id": {
"$oid": "64494e6a2f90fa940d5a4066"
}
}
],
"_id": {
"$oid": "64494e6a2f90fa940d5a4067"
}
}
],
"nbPlayers": 0,
"__v": 0
}
And I would like get the only the nbVote field in my request, I try like that :
async getNbVote(id: string) {
return this.dailyQuizModel
.findOne(
{ 'quiz.responses._id': id },
{
'quiz.responses.nbVote': 1,
},
)
.lean()
.exec();
}
For example if id === 64494e6a2f90fa940d5a405a, mongoose will return this :
{
_id: {
},
quiz: [
{
responses: [
{
nbVote: 1,
},
{
nbVote: 0,
},
{
nbVote: 0,
},
{
nbVote: 0,
},
],
},
{
responses: [
{
nbVote: 0,
},
{
nbVote: 0,
},
{
nbVote: 0,
},
{
nbVote: 1,
},
],
},
],
}
But I only want the nbVote from the Id I gave, I don't know what can i do... Thanks for help ! I Try with arrayFilters, and Aggregate but with no success
Here's one way you could do it. Comments are in the aggregation pipeline.
db.collection.aggregate([
{// find doc with correct quiz.responses._id
"$match": {
"quiz.responses._id": ObjectId("64494e6a2f90fa940d5a405a")
}
},
{
"$project": {
// only want nbVote
"_id": 0,
"nbVote": {
"$reduce": {
// input is an array of arrays
"input": "$quiz.responses",
"initialValue": null,
"in": {
"$reduce": {
// this input is an aray of objects
"input": "$$this",
// initialValue is set as outer reduce $$value
"initialValue": "$$value",
"in": {
"$cond": [
// is this the correct response?
{"$eq": ["$$this._id", ObjectId("64494e6a2f90fa940d5a405a")]},
// Yes! Get nbVote!
"$$this.nbVote",
// No. Keep current $$value
"$$value"
]
}
}
}
}
}
}
}
])
Example output:
[
{
"nbVote": 1
}
]
Try it on mongoplayground.net.
Rather than using aggregate
, you could use find
with just minor modifications. See this mongoplayground.net example that uses find
instead.