Search code examples
arraysmongodbmongodb-querymongodb-.net-driver

MongoDB: Editing Element In Array


I am wanting to edit an element that might exist in multiple arrays in a collection.

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

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

Then my class collection would look like

{
 "_id" : NUUID("..."),
  "Name" : "Computer Science",
  "Students" : [
       {
          "_id" : NUUID("..."),
           "Name" : "Chris"
           "Grade" : "A"
       },
       {
          "_id" : NUUID("..."),
           "Name" : "Bob"
           "Grade" : "B"
       }
}

And my student collection would look like

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

Now when a student updates his information I want his information to be updated in each class.

I was trying to do:

// given student that has been edited

var query = Query.EQ("Students._id", student.Id);
var update = Update<Class>
    .Pull(c => c.Students, x => x.EQ(q => q.Id, student.Id))
    .Push(c => c.Students, student)

Context.Class.Update(query,update,UpdateFlags.Multi);

But that does not work since you "cannot update Students and Students at the same time"

I was wondering is there a way to just update all that student in each array for each Class that contains that Student?

Thanks!


Solution

  • I'm not familiar with the c# driver, but this is the query that you are looking for:

    db.classes.update({
      'Students._id': some_student_id,
    }, {
      $set: {
        'Students.$.property': some_value
      }
    },{
      multi: true
    });
    

    The key concept that you are looking for is the positional $ operator. It is the index of the object that matched in the query.