Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# MongoDb C在数组元素处更新元素_C#_Mongodb_Asp.net Web Api_.net Core - Fatal编程技术网

C# MongoDb C在数组元素处更新元素

C# MongoDb C在数组元素处更新元素,c#,mongodb,asp.net-web-api,.net-core,C#,Mongodb,Asp.net Web Api,.net Core,我的文件结构如下: { "name":"Test Online", "strategies":[ { "strategyType":"Online", "strategyBudget":0, "extraElements":{ "URL":"http:\\www.google.com" } }, { "strategyType":"TV

我的文件结构如下:

{
   "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
}
我想创建一个函数来收集活动预算,将其平均分配给案例3中定义的所有策略,然后为每个策略更新strategyBudget字段

我已经创建了所有必要的对象,以便以类型安全的方式执行此操作。例如,我对战略有如下建议:

    [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; }
    }
}
所以我可以打电话给Strategy.StrategyBudget,然后我得到或设定预算

到目前为止,我的职能是:

/**
         * 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);


        }
但当我调用端点来执行此操作时,我得到以下结果:

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
如果我将更新函数更改为任何异步版本,则不会发生此错误,但不会更新startegyBudget,但会更新campaign one

我在这里做错了什么?

您的活动筛选器需要匹配数组中要使用位置运算符$更新的一个文档

这:

var-activityfilter=Builders.Filter.Eqcpg=>cpg.Id,activityid; 需要更改为以下内容:

var-activityfilter=Builders.Filter.Eqcpg=>cpg.Id,activityid &Builders.Filter.ElemMatchcpg=>cpg.Strategies,x=>x.FieldToMatch==test;
作为参考,使用本文中的数组过滤器建议是执行该操作的代码,因为在C中使用数组过滤器的示例很少:

            var campaignFilter = Builders<Campaign>.Filter.Eq(cpg => cpg.Id, campaignID);
            // mongo c# driver has yet to have a fluent syntax for Array Filters.
            var updateDefinition = Builders<Campaign>.Update.Set("Strategies.$[stra].StrategyBudget", equalBudget);

            var arrayFilterStratergy = new List<ArrayFilterDefinition>();
            arrayFilterStratergy.Add(
                 new BsonDocumentArrayFilterDefinition<BsonDocument>(new BsonDocument("stra.StrategyBudget", new BsonDocument("$gte", 0)))
            );

            // update the each strategy budget to equal value
            var resultStrategy = await _campaigns.UpdateOneAsync(
                campaignFilter,
                updateDefinition,
                new UpdateOptions { ArrayFilters = arrayFilterStratergy });

这就像一个符咒:var-campaignFilter=Builders.Filter.Eqcpg=>cpg.Id,campaignID&Builders.Filter.ElemMatchcpg=>cpg.Strategies,x=>x.StrategyBudget!=平等预算;嗯,它只是更新了第一个策略。我使用的是UpdateManyAsync。位置运算符将只更新数组中第一个匹配的元素,UpdateMany用于更新多个文档,而不是数组项。如果要对文档中的数组进行更复杂的更新,请查看数组筛选器-