【问题标题】:Error when trying to update MongoDb array element尝试更新 MongoDb 数组元素时出错
【发布时间】:2018-08-07 08:40:43
【问题描述】:

在我的 Azure CosmosDb MongoApi 中,我有带有嵌入文档数组的 JSON。

{
    "_id": ObjectId("5a95745df886842904b82f71"),
    "token": "value1",
    "channel": "value2",
    "urls":
    [
        {
            "url": "<url1>", 
            "interval": "<int>"
        },
        {
            "url": "<url2>"
            "interval": "<int>"
        }
    ]
}

我想更新特定数组元素中的“间隔”字段。问题是当我使用thisthis 之类的解决方案时,我最终会遇到异常:

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}} ); 

我的问题是导致此异常的原因以及如何避免它?

【问题讨论】:

  • 你试过db.Users.update( {"Urls.interval": 60}, {$set: {"Urls.$.interval": 30}} ); 吗?
  • @mickl 是的,抱歉,格式错误,在我的 JSON 模式中,我的“urls”小写。我会立即更新问题。

标签: c# .net mongodb azure-cosmosdb


【解决方案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() 中的条件,其粒度比位置运算符所允许的还要细。

【讨论】:

  • 非常感谢它的帮助!
猜你喜欢
  • 2013-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多