i have the following document structure:
{
"name":"Test Online",
"strategies":[
{
"strategyType":"Online",
"strategyBudget":0,
"extraElements":{
"URL":"http:\\www.google.com"
}
},
{
"strategyType":"TV",
"strategyBudget":0,
"extraElements":{
"ChannelSlots":[
{
"channelName":"SIC",
"fromHour":"13:30:00",
"toHour":"13:30:00"
},
{
"channelName":"TVI",
"fromHour":"15:30:00",
"toHour":"16:30:00"
}
]
}
},
{
"strategyType":"Outdoor",
"strategyBudget":2000,
"extraElements":{
"Latitude": 8.123456,
"Longitude": -16.123456
}
}
],
"campaignBudget":3000
}
I want to create a function that gather the campaign Budget, divide it equally by all defined strategies (in this case 3) and then updates for each strategy the strategyBudget Field.
I have created all necessary objects so that i can do this in a typesafe way. For example i have for the strategy:
[BsonDiscriminator("StrategyType", RootClass = true, Required = true)]
[BsonKnownTypes(
typeof(OnlineStrategy),
typeof(TvStrategy),
typeof(OutdoorStrategy))]
public class Strategy
{
[JsonConverter(typeof(StringEnumConverter))] // JSON.Net
[BsonRepresentation(BsonType.String)] // Mongo
public StrategyType StrategyType { get; set; }
[JsonProperty("strategyBudget")]
public int StrategyBudget { get; set; }
[JsonProperty("extraElements")]
public ExtraElements ExtraElements { get; set; }
}
}
so i can call Strategy.StrategyBudget and i get or set the budget.
My function so far is:
/**
* Divide the budget of a campaign equally between all defined strategies for that campaign
* so if a campaign has 3000 of budget and 3 strategies,
* each strategy would get 1000, and the campaign budget is set to 0
*/
private void DivideBudgetEqually(string campaignID)
{
Campaign campaignRecord = _campaigns.Find(cpg => cpg.Id == campaignID).FirstOrDefault();
int campaignBudget = campaignRecord.CampaignBudget;
int numStrategies = campaignRecord.Strategies.Count;
int equalBudget = campaignBudget / numStrategies;
var campaignFilter = Builders<Campaign>.Filter.Eq(cpg => cpg.Id, campaignID);
var strategyUpdate = Builders<Campaign>.Update.Set(cpg => cpg.Strategies[-1].StrategyBudget, equalBudget);
var campaignUpdate = Builders<Campaign>.Update.Set(cpg => cpg.CampaignBudget, 0);
// update the each strategy budget to equal value
var resultStrategy = _campaigns.UpdateMany(campaignFilter, strategyUpdate);
// update the campaign budget to 0, since we've distributed all the budget to the strategies
var resultCampaign = _campaigns.UpdateMany(campaignFilter, campaignUpdate);
}
But when i call the endpoint to execute this, i get the following:
web_1 | fail: Microsoft.AspNetCore.Server.Kestrel[13]
web_1 | Connection id "0HLVNUBP8QGRB", Request id "0HLVNUBP8QGRB:00000001": An unhandled exception was thrown by the application.
web_1 | MongoDB.Driver.MongoWriteException: A write operation resulted in an error.
web_1 | The positional operator did not find the match needed from the query.
web_1 | ---> MongoDB.Driver.MongoBulkWriteException`1[semasio_challenge_2.Models.Campaign]: A bulk write operation resulted in one or more errors.
web_1 | The positional operator did not find the match needed from the query.
web_1 | at MongoDB.Driver.MongoCollectionImpl`1.BulkWrite(IClientSessionHandle session, IEnumerable`1 requests, BulkWriteOptions options, CancellationToken cancellationToken)
web_1 | at MongoDB.Driver.MongoCollectionImpl`1.<>c__DisplayClass23_0.<BulkWrite>b__0(IClientSessionHandle session)
web_1 | at MongoDB.Driver.MongoCollectionImpl`1.UsingImplicitSession[TResult](Func`2 func, CancellationToken cancellationToken)
web_1 | at MongoDB.Driver.MongoCollectionImpl`1.BulkWrite(IEnumerable`1 requests, BulkWriteOptions options, CancellationToken cancellationToken)
web_1 | at MongoDB.Driver.MongoCollectionBase`1.<>c__DisplayClass92_0.<UpdateMany>b__0(IEnumerable`1 requests, BulkWriteOptions bulkWriteOptions)
web_1 | at MongoDB.Driver.MongoCollectionBase`1.UpdateMany(FilterDefinition`1 filter, UpdateDefinition`1 update, UpdateOptions options, Func`3 bulkWrite)
web_1 | --- End of inner exception stack trace ---
web_1 | at MongoDB.Driver.MongoCollectionBase`1.UpdateMany(FilterDefinition`1 filter, UpdateDefinition`1 update, UpdateOptions options, Func`3 bulkWrite)
web_1 | at MongoDB.Driver.MongoCollectionBase`1.UpdateMany(FilterDefinition`1 filter, UpdateDefinition`1 update, UpdateOptions options, CancellationToken cancellationToken)
web_1 | at semasio_challenge_2.Services.CampaignService.DivideBudgetEqually(String campaignID) in /src/Services/CampaignService.cs:line 109
If i change the update function to any Async version, this error doesn't happen, but startegyBudget is not updated, but campaign one is.
What i'm doing wrong here?