In the function below, if the user, topic and subtopic do not exist, a new testRecord is inserted into the testRecords array of the User collection. This works fine. On the other hand, if the combination of the user, topic and subtopic exist, only the scores array of testRecords is to be populated with the new scores. This is not working. The code segment that begins: if(existingTopicSubtopic) is the part that is not working.
exports.updateUserTestRecord = async (req, res) => {
console.log('req.body', req.body)
const {topicName, subtopicName, rightAnswers, wrongAnswers, date} = req.body;
const {
userId
} = jwt.verify(req.headers.authorization, process.env.JWT_SECRET);
const existingTopicSubtopic = await User.findOne(
{
_id: userId,
'testRecords.topic': topicName,
'testRecords.subtopic': subtopicName
},
)
let user;
if(existingTopicSubtopic) {
console.log('EXISTING USER')
user = await User.findOneAndUpdate(
{
_id: userId,
'testRecords.topic': topicName,
'testRecords.subtopic': subtopicName
},
{
$addToSet : {
testRecords : [
{
'scores.$.rightAnswers': rightAnswers,
'scores.$.wrongAnswers': wrongAnswers,
'scores.$.date': date,
}
]
}
},
)
} else {
console.log('NOT EXISTING USER')
user = await User.findOneAndUpdate(
{
_id: userId,
},
{
$addToSet : {
testRecords : [
{
topic: topicName,
subtopic: subtopicName,
scores: [
{
rightAnswers,
wrongAnswers,
date,
}
]
}
]
}
},
)
}
}
asked Feb 6, 2023 at 18:31
koque
2,3066 gold badges33 silver badges58 bronze badges
1 Answer 1
For inner array operation, we need to use $[identifier] like $[element]. In your case:
if (existingTopicSubtopic) {
await User.findOneAndUpdate(
{
_id: userId,
"testRecords.topic": topicName,
"testRecords.subtopic": subtopicName,
},
{
$addToSet: {
"testRecords.$[element].scores": {
rightAnswers: rightAnswers,
wrongAnswers: wrongAnswers,
date,
},
},
},
{
arrayFilters: [
{
"element.topic": topicName,
"element.subtopic": subtopicName,
},
],
}
);
} else {
await User.findOneAndUpdate(
{
_id: userId,
},
{
$addToSet: {
testRecords: {
topic: topicName,
subtopic: subtopicName,
scores: [
{
rightAnswers,
wrongAnswers,
date,
},
],
},
},
}
);
}
answered Feb 7, 2023 at 4:01
hungtran273
1,38512 silver badges16 bronze badges
Sign up to request clarification or add additional context in comments.
1 Comment
koque
Brilliant. Worked on the first try. Thank you.
lang-js