I'm trying to return a subdocument that matches the query fields. I just want to return the PIN that matches the user, which is held in the account collection. This is what I've got so far.
router.post('/SelectUser', async(req, res) =>{
try{
const acc = await Account.findOne({"Email": req.body.Email});
if(!acc) throw Error('Email not found');
var user = await Account.findOne({"Users.Username":req.body.User.Username},{Users:{PIN:1}});
}
This outputs all the PINs associated with an account, which isn't what I want. Here are the Schemas and Models that I'm using:
Account:
const User = require('../Models/UserData');
const AccountSchema = new Schema({
// Email linked to this account
Email:{
type:String,
unique:true,
required:true,
index:true
},
// Password for the account
Password:{
type : String,
required : true
},
// Users on this account
Users:{
type:[User],
required:true
}
});
module.exports = mongoose.model('Account', AccountSchema);
User:
const UserSchema = new Schema({
// Name of the user
Username:{
type:String,
required:true,
unique:true
},
// PIN for each user
PIN:{
type:Number,
require:true
}
});
module.exports = UserSchema;
What you're trying to do would be pretty trivial in your app (i.e JS code after findOne), but if you really want to do it in mongodb, then you will need to use aggregation. Change your code to:
const username = req.body.User.Username;
const user = await Account.aggregate([
{
$match: {
"Users.Username": username
}
},
{
"$project": {
_id: false,
USER: {
$filter: {
input: "$Users",
as: "users",
cond: {
$eq: [
"$$users.Username",
username
]
}
}
}
}
},
{
"$unwind": "$USER"
},
{
"$project": {
USER_PIN: "$USER.PIN"
}
}
]);
if(user.length){
console.log(user[0].USER_PIN)
}else{
console.log('Username not found')
}
Here is the actual aggregation query for you to play around with: https://mongoplayground.net/p/o-xTTa8R42w