Reputation: 1360
I want to update a document and set a value to an array of subdocument.
Using the documentation I have to use the $[]
operator.
Following this link it is now possible to do stuff like this :
db.coll.update({}, {$set: {“a.$[].b”: 2}})
Input: {a: [{b: 0}, {b: 1}]}
Output: {a: [{b: 2}, {b: 2}]}
For example this request will do the job in my case :
db.collection.update(
{ "History": { "$elemMatch": { "status": { "$ne": "PROCESSED" } } } },
{ "$set": { "History.$[].flag": false } },
{ "multi": true }
)
But I do not find the way to do the $[]
operator in C# with the driver.
And the driver documentation does not contain the information.
Can someone please provide me a C# sample.
Upvotes: 3
Views: 1139
Reputation: 5669
you can achieve it like this:
collection.UpdateMany(
x => x.History.Any(h => h.status != "PROCESSED"),
Builders<YourType>.Update.Set("History.$[].flag", false));
here's an alternative strongly-typed solution:
using MongoDB.Entities;
using MongoDB.Entities.Core;
using System.Linq;
namespace StackOverflow
{
public class Test : Entity
{
public Event[] History { get; set; }
}
public class Event
{
public bool flag { get; set; }
public string status { get; set; }
}
public class Program
{
private static void Main(string[] args)
{
new DB("test", "localhost");
(new[] {
new Test { History = new[]{
new Event { flag = true, status = "PROCESSED" } } },
new Test { History = new[]{
new Event { flag = true, status = "NOT-PROCESSED" },
new Event { flag = true, status = "NOT-PROCESSED" }
}}
}).Save();
var field = Prop.PosAll<Test>(t => t.History[0].flag);
DB.Update<Test>()
.Match(t => t.History.Any(h => h.status != "PROCESSED"))
.Modify(b => b.Set(field, false))
.Execute();
}
}
}
Upvotes: 3
Reputation: 516
Let's suppose that you have an object called History
:
public class History : MongoDocument
{
// here you have some other properties, and you have a list of objects
public Guid Guid { get; private set; }
public List<SOME_OBJECT> NAME_OF_THE_ARRAY { get; set; }
}
And SOME_OBJECT:
public class SOME_OBJECT
{
// here you have other properties
public bool Flag { get; set; }
public string Name { get; set; }
}
And you want to update all objects into NAME_OF_THE_ARRAY:
public async Task<bool> Update_NAME_OF_THE_ARRAY(string id)
{
var filter = Builders<History>.Filter.Eq("_id", ObjectId.Parse(id));
var update = Builders<History>.Update.Combine(
Builders<History>.Update.Set(x => x.NAME_OF_THE_ARRAY[-1].Name, "test")
Builders<History>.Update.Set(x => x.NAME_OF_THE_ARRAY[-1].Flag, false);
var result = await _historyCollection.UpdateOneAsync(filter, update);
return result.ModifiedCount > 0;
}
Upvotes: -1