如何使用 C# MongoDB.Driver 更新深层嵌套数组?
How to update deeply nested array with C# MongoDB.Driver?
我有这样的模型:
{
"_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",
}
]
}
]
}
我正在尝试为 "key":"testKey2"
更新 value
我有这样的更新声明:
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));
当我尝试使用这样的过滤器 ConfigGroup[-1]
更新 groupName
时,它起作用了。
但是在我们有 ConfigGroup[-1].Config[-1]
的情况下它不起作用。
我知道如何更新值的两个选项:
- 只需使用
ConfigGroup[-1].Config
更新整个列表
- 或为过滤器指定具体索引,如
ConfigGroup[configGroupIndex].Config[configKeyIndex].Value
但我想知道为什么它不适用于 -1
索引。
以及如何正确地做到这一点。
请使用c#MongoDB.Driver.
回答
提前致谢。
之所以不能和乘法'-1'
一起工作是因为它和positional operator$
是一样的。
在"Nested Arrays"主题下的官方文档中我们可以看到下一个:
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
从 MongoDb 3.6 开始,有允许使用嵌套数组的新功能。
The filtered positional operator:
The filtered positional operator $[<identifier>]
identifies the array
elements that match the arrayFilters conditions for an update
operation
因此,使用过滤后的位置运算符,我的代码现在如下所示:
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))
}
});
我有这样的模型:
{
"_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",
}
]
}
]
}
我正在尝试为 "key":"testKey2"
value
我有这样的更新声明:
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));
当我尝试使用这样的过滤器 ConfigGroup[-1]
更新 groupName
时,它起作用了。
但是在我们有 ConfigGroup[-1].Config[-1]
的情况下它不起作用。
我知道如何更新值的两个选项:
- 只需使用
ConfigGroup[-1].Config
更新整个列表
- 或为过滤器指定具体索引,如
ConfigGroup[configGroupIndex].Config[configKeyIndex].Value
但我想知道为什么它不适用于 -1
索引。
以及如何正确地做到这一点。
请使用c#MongoDB.Driver.
回答提前致谢。
之所以不能和乘法'-1'
一起工作是因为它和positional operator$
是一样的。
在"Nested Arrays"主题下的官方文档中我们可以看到下一个:
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
从 MongoDb 3.6 开始,有允许使用嵌套数组的新功能。
The filtered positional operator:
The filtered positional operator
$[<identifier>]
identifies the array elements that match the arrayFilters conditions for an update operation
因此,使用过滤后的位置运算符,我的代码现在如下所示:
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))
}
});