在我的Azure CosmosDb MongoApi中,我有一个带有嵌入文档数组的JSON。
{
"_id": ObjectId("5a95745df886842904b82f71"),
"token": "value1",
"channel": "value2",
"urls":
[
{
"url": "<url1>",
"interval": "<int>"
},
{
"url": "<url2>"
"interval": "<int>"
}
]
}
我想更新特定数组元素中的“interval”字段。问题是,当我使用this或this等解决方案时,我最终会遇到异常:
MongoDB.Driver.MongoCommandException: Command findAndModify failed: Invalid BSON field name 'urls.$.interval'.
所以,我决定尝试在Mongo Shell中运行查询并得到同样的错误:
{
"nMatched": 0,
"nUpserted": 0,
"nModified": 0,
"writeError":
{
"code": 2,
"errmsg": "Invalid BSON field name 'urls.$.interval'"
}
}
这是我的C#代码:
var filterBuilder = Builders<User>.Filter;
var filter = filterBuilder.Where(p => p.Token == model.Token && p.Channel == model.Channel && p.Urls.Any( u => u.Url == model.Url));
var update = Builders<User>.Update.Set(p => p.Urls.ElementAt(-1).interval, 5);
await _context.Users.FindOneAndUpdateAsync<User>(filter, update);
这是我的MongoDb shell请求:
db.Users.update( {"urls.interval": 60}, {$set: {"urls.$.interval": 30}} );
我的问题是导致此异常的原因,我该如何避免呢?
答案 0 :(得分:1)
Cosmos DB目前不支持位置运算符。请使用以下解决方法:迭代客户端上的文档和数组元素,更改所需元素并使用新数组对文档发出更新: 例如,假设您拥有以下元素的集合用户:
{ "_id" : ObjectId("59d6b719708b990d6c9b3aca"), "tags" : [ { "id" : 1, "value" : "11" }, { "id" : 2, "value" : "22" }, { "id" : 3, "value" : "32" } ] }
...您可以发出以下命令来获取其中一个元素(在这种情况下id = 1)更新:
db.users.find().forEach( function(user) { user.tags.forEach( function(tag) { if (tag.id=="1") { tag.value = "Updated!"; db.users.updateOne({_id : user._id}, {$set: {"tags": user.tags}}); } } ); } );
您可以使用比位置操作符允许的更精细的粒度调整if()中的条件。