Search code examples
mongodbmongodb-querymongodb-.net-driver

Mongodb remove array with id .Net


I have collections student and class.

Class contains an array of students. Whenever a student is edited it will also be edited in all the classes that the student is in.

So when a student is deleted I also want it to be deleted from all the classes it is in.

Right now I am having to pass the whole student to pull from the class

var query = Query.EQ("Students._id", idOfStudent);
var update = Update<Class>.Pull(x => x.Students, studentToRemove);

Is there a better way to pull where I can just pass in the student id for that student?

EDITED

public class Student
{
   [BsonId]
   public Guid Id {get; set;}
   public string Name {get; set;}       
}

public class Class
{
   [BsonId]
   public Guid Id {get; set;}
   public string Grade {get; set;}
   public List<Student> Students {get; set;}  
}

Then my class collection would look like

{
    "_id" : NUUID("..."),
    "Grade" : "5th",
    "Students" : [
           {
              "_id" : NUUID("..."),
               "Name" : "Chris"
           },
            {
              "_id" : NUUID("..."),
               "Name" : "Bob"
           }
}

And my student collection would look like

  {
    "_id" : NUUID("..."),
    "Name" : "Chris"
  }

When someone deletes Student 'Chris' they supply an id which will be used to find the student and delete it, but I also want to take that id and pull that student from all the Classes they are in.


Solution

  • Yes, you can, using the unique identifier in your student:

    var joe = new Student { Name = "Joe", Id = Guid.NewGuid() };
    /// ....
    var query = Query<Class>.EQ(p => p.Id, doc.Id);
    var update = Update<Class>.Pull(r => r.Students, p => p.EQ(q => q.Id, joe.Id));
    

    Hints:

    1. Remember that GUIDs provide bad data locality - that can be a problem or it can be advantageous, but most data roughly has creation-time locality, so ObjectId is often a better bet.
    2. I'd suggest you use the same coding style - either expression based, or string based, but your query uses the string-based notation while the update uses an expression