Mongodb's associated query $lookup

  • now there are such data structures, such as
in the collection class.
    {
        _id:ObjectId123456789...),
        number:10,
        students:[
            {
                studentId:ObjectId(123456789...)/* studentid */
            },
            {
                studentId:ObjectId(123456789...)/* studentid */
            },
            ...
        ],
        teacher:ObjectId(123456789...),
        
    }
The data structure of
  • student collection is
    {
        _id:ObjectId(123456789...);
        name:"zhangsan",
        age:20,
    }
  • now the requirement is to take out the student when querying class, so it needs to be associated with the query. I use the $lookup, of pipeline, but it seems that I can only query the attributes at the next level of class, such as the association query teacher
.
    db.class.aggregate([
       {
          $lookup:
             {
                from: "teacher",
                localField: "teacher",
                foreignField: "_id",
                as: "teacher"
            }
       }
    ])
  • but studentId, under student cannot be implemented. I have tried
    db.class.aggregate([
       {
           $unwind:students,
       },
       {
          $lookup:
             {
                from: "student",
                localField: "students.studentId",
                foreignField: "_id",
                as: "student",/* student */
            }
       }
    ])
  • I hope there is a boss who can solve the problem! Cannot change data structure
Mar.28,2021

the first thing to do with MongoDB is to forget about the relational model and make full use of anti-paradigm and redundancy to achieve maximum read and write efficiency. You have found that the current data model does not work, why not change the way to solve the problem?
what determines the data model is how you need to use the data. Without knowing how you plan to use the data, here are some common-sense speculations.
there are now three entities involved:

  • teacher
  • student
  • class

where:

  • teacher:class = 1 li n
  • class:student = 1 li n

in the case of 1-type n, the most common practice is to make 1 redundant to n. For example, students can be:

{
    _id:ObjectId(123456789...),
    name:'zhangsan',
    age:20,
    class: {
        classId: ObjectId(123456789...),
        number:10,
        // 
    }
}

of course, you don't need the details of class. After all, students in a class only need to check the class information once.

{
    _id:ObjectId(123456789...),
    name:'zhangsan',
    age:20,
    classId: ObjectId(123456789...)
}
Is it more convenient to use

?
Yes, redundancy can lead to data inconsistencies, but do you really care so much about consistency? The usual answer is no.
for example, what if the class information is to be modified? That will cause each student's class information to be updated again, and the revision will be more stressful and the operation will be more complicated. But don't forget that most of the pressure on your system comes from reading rather than writing. What is the probability of class revision? Maybe not once in a few months. But what is the probability of going to class? Maybe many times a day. It is self-evident to compare which is the most important.

to sum up, don't use paradigms to constrain yourself when using MongoDB, just consider performance and ease of use.

Menu