1

I have an object like that:

public class Foo {
     public string Id {get;set;}
     public List<Bar> Bars {get;set;}
}

public class Bar {
     public string Id {get;set;}
     public bool Read {get;set;}
}

I would like to update multiple bars basead on a list of bar ids. I am trying to do something like that, but it only updates one record instead of multiple:

public bool MarkAsRead(string fooId, List<string> barIds)
        {
            var @in = new FilterDefinitionBuilder<Bar>().In(x => x.Id, barIds);

            var filter = Filter().Eq(x => x.Id, fooId) & Filter().ElemMatch(x => x.Bars, @in);

            var update = UpdateFilter()
                .Set(x => x.Bars[-1].Read, true);

            var result = collection.UpdateOne(filter, update);

            return result.MatchedCount > 0;
        }

How can I do that?

Nic Cottrell
  • 9,401
  • 7
  • 53
  • 76
MuriloKunze
  • 15,195
  • 17
  • 54
  • 82
  • 1
    Have you seen this? https://stackoverflow.com/questions/48868243/c-sharp-mongodb-how-to-update-nested-array-elements/ – dnickless May 15 '18 at 19:50

1 Answers1

4

Here's a version that works for me using the latest version of the driver (v2.7) - I think it works from v2.5 onwards:

public bool MarkAsRead(string fooId, List<string> barIds)
{
    Expression<Func<Foo, bool>> filter = f => f.Id == fooId;
    var update = Builders<Foo>.Update.Set("Bars.$[i].Read", true );
    var arrayFilters = new List<ArrayFilterDefinition> { new JsonArrayFilterDefinition<Bar>("{'i._id': { $in: ["+string.Join(",", barIds.Select(s => string.Format("\"{0}\"", s)).ToArray())+"]}}") };
    var updateOptions = new UpdateOptions { ArrayFilters = arrayFilters };

    var result = collection.UpdateOne(filter, update, updateOptions);

    return result.MatchedCount > 0;
}
dnickless
  • 10,733
  • 1
  • 19
  • 34