在MongoDB中查询和分组?

3

第一部分:

我有一个(学生)集合:

 {
    sname : "",
    studentId: "123"
    age: "",
    gpa: "",
 }

我正在尝试从中仅获取两个键:

我正在尝试从中仅获取两个键:

{
    sname : "",
    studentId: "123"
}

我需要去掉年龄和GPA,只保留姓名和学生ID,如何做到?

第二部分:

然后我有一个“subject”集合:

{
    subjectName : "Math"
    studentId : "123"
    teacherName: ""
 }

我需要将上一部分(part1)中的前面的键与正确的学生ID匹配/组合,以便最终得到如下结果:
 {
    sname : "",
    studentId: "123",
    subjectName : "Math" 

 }

我该怎么做才能得到结果?我尝试阅读有关分组和MapReduce的资料,但没有找到清晰的示例。

2个回答

4
回答你的第一个问题,你可以这样做:
db.student.find({}, {"sname":1, "studentId":1});

第一个{}是限制查询条件,此处包括整个集合。第二部分指定键值为1或0,取决于您是否需要它们。请勿在单个查询中混合使用包含和排除。除了一些特殊情况,Mongo将不接受。

您的第二个问题更难。您要求的是连接操作,但Mongo不支持。无法通过studentId连接这两个集合。您需要找到所有所需的学生,然后使用这些studentIds查找所有匹配的科目。然后,您需要在自己的代码中合并这两个结果。您可以通过您使用的任何驱动程序来完成此操作,或者您可以在shell本身的JavaScript中完成此操作,但无论哪种方式,都必须使用自己的代码进行合并。

编辑: 以下是如何在shell中执行此操作并将输出发送到名为“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});
      }
    );
  }
);

如果这不是经常变化的数据,您可以使用此shell脚本删除“out”集合并定期重新填充它。然后您的代码可以直接从“out”查询。如果数据经常更改,则需要在代码中即时合并。
另一个可能更好的选择是将“subject”数据包含在“student”集合中,反之亦然。这将导致更符合mongodb的结构。如果您经常遇到这种连接问题,则mongo可能不适合您的需求,关系数据库可能更适合。

1
您还可以使用$in运算符来减少生成“out”表所需的查询数量。这在高负载或跨网络查询大量学生时尤为重要,因为往返时间可能成为一个因素。 - dcrosta

1
Mongo的find()操作符允许您在结果中包含或排除某些字段。
在文档中查看字段选择以获取更多信息。您可以执行以下任一操作:
db.users.find({}, { 'sname': 1, 'studentId': 1 });
db.users.find({}, { 'age': 0, 'gpa': 0 });

为了将您的学生和课程联系在一起,您可以分别查找学生所选的课程,例如:

db.subjects.find({ studentId: 123 });

或者将主题数据与每个学生一起嵌入,并与学生文档一起检索:

{
    sname : "Roland Browning",
    studentId: "123"
    age: 14,
    gpa: "B",
    subjects: [ { name : "French", teacher: "Mr Bronson" }, ... ]
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接