Чтобы ответить на ваш первый вопрос, вы можете сделать это:
db.student.find({}, {"sname":1, "studentId":1});
Первый {} в этом запросе ограничения, который в этом случае включает в себя всю коллекцию. Вторая половина определяет ключи с 1 или 0 в зависимости от того, хотите ли вы их вернуть. Не смешивайте include и exclude в одном запросе. За исключением пары особых случаев, Монго не примет это.
Ваш второй вопрос сложнее. То, что вы просите, это объединение, и монго это не поддерживает. Невозможно соединить две коллекции в studentId. Вам нужно будет найти всех учеников, которых вы хотите, а затем использовать эти идентификаторы учеников, чтобы найти все подходящие предметы. Затем вам нужно объединить два результата в ваш собственный код. Вы можете сделать это через любой драйвер, который вы используете, или вы можете сделать это в javascript в самой оболочке, но в любом случае вам придется объединить их с вашим собственным кодом.
Edit:
Вот пример того, как вы можете сделать это в оболочке с выводом в коллекцию с именем out.
db.student.find({}, {"sname":1, "studentId":1}).forEach(
function (st) {
db.subject.find({"studentId":st.studentId}, {"subjectName":1}).forEach(
function (sub) {
db.out.insert({"sname":st.sname, "studentId":st.studentId, "subjectName":sub.subjectName});
}
);
}
);
Если эти данные не так часто меняются, вы можете просто удалить коллекцию "out" и периодически заполнять ее с помощью этого сценария оболочки. Тогда ваш код может запрашивать напрямую из «вне». Если данные часто меняются, вы захотите сделать это в своем коде на лету.
Другой, и, возможно, лучший вариант, это включить данные «предмета» в коллекцию «ученик» или наоборот. Это приведет к более дружественной структуре mongodb. Если вы часто сталкиваетесь с этой проблемой объединения, монго может оказаться не лучшим способом, и реляционная база данных может лучше соответствовать вашим потребностям.