I have a studentsubject schema.
Properties are subject_id,student_id,class_id
So my usecase is i want to find the one student where class_id, student_id matches. Subject id is optional. Means if subject id is present with that student and class id , then pick that student where all 3 id : class id,student id and subject id matches (because it is priority). Else pick the student where student id and class id matches, subject id might be different.
Ps: there might be multiple documents with same class id and student id. If we include subject id then it identify one document.
I tried this one
studentsubject.findone({
student_id: studentId,
class_id : classId,
$or:[
{
subject_id : subjectId
},
{
subject_id : {$exists:true}
}
]
})
It fetches the first matched document where class id and student id matches, not looking for existing data where subject id matches
2
Answers
The simplest solution would be to use a JS script. This one should work for your example:
Then you can run this script by using
load('path/to/script.js')
. Obviously, you need to provide the values, because in this script studentId, classId and subjectId are undefined.Its because you are giving an
or
statementsubject_id : {$exists:true}
. your query states:Match student_id, match class_id, and match subject_id
OR
Match student_id, match class_id, and just check if the document is assigned a subject_id irrespective of its value
Solution
Just remove
subject_id : {$exists:true}
. Your query should look like this:Explanation
Lets take this sample data:
Let this be your query:
This will check for student_id: 1, class_id: A, and subject_id: English OR student_id: 1, class_id: A, and if there is any subject_id assigned. So it iterates through the document and stumbles upon this first:
The student_id and class_id matches, and
subject_id : {$exists:true}
as a subject_id does exist there, hence returning this document.So modify your query to this:
This will check if all three matches, and don’t worry if a document doesn’t have
subject_id
field, the query will skip it as it doesn’t meet all the requirements.