Reputation: 55
I currently find the main document, in this case User, then loop over user.characters and find the correct subdocument and return it.
getSingleCharacter: async function (req, res) {
// uses req.params.characterName to search for a character
try {
const user = await db.Users.findbyId(req.user._id)
const charactersArr = user.characters
charactersArr.forEach(element => {
if (req.params.characterName === element.playerName) {
res.json(element)
}
});
res.json(user)
} catch (error) {
console.log(error)
res.status(error)
}
}
I wanted to see if I could avoid using this for loop and tried using a bit of code I had in a findOneAndUpdate query I had
getSingleCharacter: async function (req, res) {
// uses req.params.characterName to search for a character
try {
const user = await db.Users.findOne({_id: req.user._id, "characters.playerName": req.params.characterName })
res.json(user)
} catch (error) {
console.log(error)
res.status(error)
}
}
This does not return the specific character and instead returns the whole user. Is there something that I could change to avoid using this for loop?
Upvotes: 2
Views: 29
Reputation: 430
you can use aggregation to achieve this goal:
const user = await db.Users.aggregate([
{
'$match': {
'_id': req.user._id
}
}, {
'$unwind': {
'path': '$characters'
}
}, {
'$match': {
'characters.playerName': req.params.characterName
}
}
])
first of all, we must filter users to select target records. then we must unwind the characters array to make multiple records that each record contains one of the characters. Eventually, we must filter our target characters.playerName field.
Upvotes: 0