How to join DBRef objects in mongo

11,561

Solution 1

You can use @DBRef to refer the Subjects document from Student.

The mapping framework doesn't have to store child objects embedded within the document. You can also store them separately and use a DBRef to refer to that document. When the object is loaded from MongoDB, those references will be eagerly resolved and you will get back a mapped object that looks the same as if it had been stored embedded within your master document.

Here's an example of using a DBRef to refer to a specific document that exists independently of the object in which it is referenced (both classes are shown in-line for brevity's sake):

Refer this link

Another SO link

Edit:-

Actually, to give you more details, the @DBRef annotation will eagerly load the data (i.e. Subjects in this case).

Students model class:-

@Document(collection = "students")
public class Students implements Serializable, BaseDocument {

    private static final long serialVersionUID = -3534650012619938612L;

    @Id
    private String id;

    @Field("class")
    private String className;

    @DBRef
    @Field("subjects")
    private Subject subject;

    public String getId() {
        return id;
    }

    public String getClassName() {
        return className;
    }

    public void setId(String id) {
        this.id = id;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public Subject getSubject() {
        return subject;
    }

    public void setSubject(Subject subject) {
        this.subject = subject;
    }

    @Override
    public String toString() {
        return "Students [id=" + id + ", className=" + className + ", subject=" + subject + "]";
    }
}

Subjects model class:-

@Document(collection = "subjects")
public class Subject implements Serializable, BaseDocument {

    private static final long serialVersionUID = -3534650012619938612L;

    @Id
    private String id;

    private String sub1;
    private String sub2;

    public String getId() {
        return id;
    }

    public String getSub1() {
        return sub1;
    }

    public String getSub2() {
        return sub2;
    }

    public void setId(String id) {
        this.id = id;
    }

    public void setSub1(String sub1) {
        this.sub1 = sub1;
    }

    public void setSub2(String sub2) {
        this.sub2 = sub2;
    }

    @Override
    public String toString() {
        return "Subject [id=" + id + ", sub1=" + sub1 + ", sub2=" + sub2 + "]";
    }

}

Get Student by Id:-

When you get students by Id, the framework/mongodb will automatically load the subject data. You don't need to specifically do join to get the subject data.

public Students getStudents(String id) {

        MongoOperations mongoOperations = getMongoConnection();

        Students students = mongoOperations.findById(id, Students.class);

        System.out.println(students.toString());

        return students;

    }

Output:-

Students [id=584ea66e9e53b7802651de36, className=1, subject=Subject [id=class1, sub1=english, sub2=physics]]

Subjects collection:-

{
    "_id" : "class1",
    "sub1" : "english",
    "sub2" : "physics"
}

Students collection:-

{
    "_id" : ObjectId("584ea66e9e53b7802651de36"),
    "name" : "abc",
    "class" : "1",
    "subjects" : {
        "$ref" : "subjects",
        "$id" : "class1",
        "$db" : "localhost"
    }
}

Solution 2

You can make your student collection like this:

    students 
{
 "name" : "abc"
 "class" : "1"
 "subjects" : [{ type: Schema.Types.ObjectId}] // You will store Objectids of subject
}

Now when you do find query on student then populate the data.

Share:
11,561
Ravi Teja
Author by

Ravi Teja

Updated on June 21, 2022

Comments

  • Ravi Teja
    Ravi Teja almost 2 years

    Hi I am having my first collection

        students 
    {
     "name" : "abc"
     "class" : "1"
     "subjects" : DBRef("subjects","class1")
    }
    

    and my second collection

     subjects
    {
     "_id" : "class1"
     "sub1" : "english"
     "sub2" : "physics"
    }
    

    I want to achieve my output as below my joining the above two collections

       {
     "name" : "abc"
     "class" : "1"
     "subjects" : {sub1 : "english",sub2 : "physics"}
    }
    

    Is it possible,if yes how?

  • Ravi Teja
    Ravi Teja over 7 years
    thanks for your links. But I want to perform join to combine data. Is it possible?
  • notionquest
    notionquest over 7 years
    When you get students, you will get subjects object. I hope that is what you are expecting. As mentioned in API doc, it will be eagerly loaded. I have used it before.
  • Ravi Teja
    Ravi Teja over 7 years
    sorry,since i am very new to this can u please explain in detail.