How to update deeply nested array with C# MongoDB.Driver?

倾然丶 夕夏残阳落幕 提交于 2021-02-07 02:56:14

问题


I have such model:

{  
   "_id":"5b90eea8c02e062be2888446",
   "storeGuid":"e97d4730-9b8a-49ed-be87-caf4054439aa",
   "storeId":"0",
   "storeDbName":"0",
   "tenant":"dev",
   "configGroup":[  
      {  
         "groupName":"peopleCounter",
         "config":[  
            {  
               "key":"averageWaitPeriodTime",
               "value":"60",
            }
         ]
      },
      {  
         "groupName":"sessionMonitor",
         "config":[  
            {  
               "key":"testKey1",
               "value":"987",
            },
            {  
               "key":"testKey2",
               "value":"123",
            }
         ]
      }
   ]
}

I am trying to update value for "key":"testKey2"

I have such update statement:

await coll.UpdateOneAsync(
    x => x.StoreGuid == storeGuid
         && x.ConfigGroup.Any(y => y.GroupName == groupName
                                   && y.Config.Any(z => z.Key == model.Key)),
    Builders<StoreModel>.Update.Set(x => x.ConfigGroup[-1].Config[-1].Value, model.Value));

When i try to update for example groupName using such filter ConfigGroup[-1] it works.

But in the case when we have ConfigGroup[-1].Config[-1] it does not work.

I know two options how to update the value:

  • just update whole list using ConfigGroup[-1].Config
  • or specify concrete indexes for filter like ConfigGroup[configGroupIndex].Config[configKeyIndex].Value

But i want to know why it does not work with -1 index. And how to do it properly.

Please answer using c# MongoDB.Driver.

Thanks in advance.


回答1:


The reason why it does not work with multiply '-1' because it is the same as positional operator $. In official documentation under the subject of "Nested Arrays" we can see next:

The positional $ operator cannot be used for queries which traverse more than one array, such as queries that traverse arrays nested within other arrays, because the replacement for the $ placeholder is a single value

From MongoDb 3.6 there are new features that allow to work with nested arrays.

The all positional operator

The filtered positional operator:

The filtered positional operator $[<identifier>] identifies the array elements that match the arrayFilters conditions for an update operation

So, using the filtered position operator my code looks like this now:

await coll.UpdateOneAsync(x => x.StoreGuid == storeGuid,
    Builders<StoreModel>.Update.Set("configGroup.$[g].config.$[c].value", model.Value),
    new UpdateOptions
    {
        ArrayFilters = new List<ArrayFilterDefinition>
        {
            new BsonDocumentArrayFilterDefinition<BsonDocument>(new BsonDocument("g.groupName", groupName)),
            new BsonDocumentArrayFilterDefinition<BsonDocument>(new BsonDocument("c.key", model.Key))
        }
    });


来源:https://stackoverflow.com/questions/52311508/how-to-update-deeply-nested-array-with-c-sharp-mongodb-driver

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!