问题
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