在 mongo 和 upsert 中更新数组

Posted

技术标签:

【中文标题】在 mongo 和 upsert 中更新数组【英文标题】:Update array in mongo and upsert 【发布时间】:2014-12-06 21:04:00 【问题描述】:

我正在尝试更新文档中的数组并且它可以正常工作,但是当我想使用 upsert 添加新元素时如何运行错误。我在google上搜索了几个小时,mongodb文档和我尝试过的都无法操作。

集合的结构是:


"name" : String,
"providerId": Number,
"description": String,
"providers": [
    
        "merchantId": String,
        "name": String,
        "valid": Boolean,
        "data": String
    ,
    
        "merchantId": String,
        "name": String,
        "valid": Boolean,
        "data": String
    ,
    
        "merchantId": String,
        "name": String,
        "valid": Boolean,
        "data": String
    
]

使用此查询更新现有数据:

db.collection.update(  "providerId": ID, "providers":  $elemMatch:  "merchantId": MERCHANTID ,  $set: 

    "providers.$.merchantId": MERCHANTID,
    "providers.$.name": NAME,
    "providers.$.valid": true,
    "providers.$.data": DATA

);

这工作正常且正确地更新了我的数组元素。我想在元素不存在时添加它,而不知道是否有项目,但如果可能的话,探测以添加 upsert ( upsert: true ) 参数,但给我以下错误。我认为是因为它没有返回任何对象搜索。

这是错误:

MongoError:位置运算符未从查询中找到所需的匹配项。未扩展更新:providers.$.name

有没有办法更新数组中子文档中的数据,并且如果它们不存在则与添加新的兼容?我尝试使用运算符 $in 进行搜索,但它给了我错误;还探测以不同方式进行搜索( "providers.merchantId": MERCHANTID )和其他方式。

谢谢

【问题讨论】:

您能否告诉我“providers.$.merchantId”中的 $ 被称为或记录了什么?我遇到了一些奇怪的问题,并试图弄清楚它到底是做什么的。 【参考方案1】:

有一个选项可以实现您想要的。

// step 1
var writeResult = db.collection.update(
    "providerId" : ID,
    "providers" : 
        $elemMatch : 
            "merchantId" : MERCHANTID
        
    
, 
    $set : 
        "providers.$.merchantId" : MERCHANTID,
        "providers.$.name" : NAME,
        "providers.$.valid" : true,
        "providers.$.data" : DATA
    
);


// step 2
if (!writeResult.nModified)  // if step 1 has succeeded on update, nModified == 1, else nModified == 0
    db.collection.update(
        "providerId" : ID,
        "providers.merchantId" : 
            $ne : MERCHANTID        // this criteria is necessary to avoid concurrent issue
        
    , 
        "$push" : 
            "prividers" : 
                "merchantId" : MERCHANTID,
                "name" : NAME,
                "valid" : true,
                "data" : DATA
            
        
    );

【讨论】:

好的,本来想做类似的事情,但我认为就像他不知何故强行插入一样。谢谢@Wizard @Anto,你的意思是可能找不到指定 providerId 的文档,需要插入整个文档吗? 曾想过做一些类似于你所说的事情(做一个更新,如果它返回错误尝试它),但我认为就像在 mongodb 中有一些本机一样,好像它没有存在添加它,所以问,因为我是新手,不知道mongoDB的所有运算符和功能;)

以上是关于在 mongo 和 upsert 中更新数组的主要内容,如果未能解决你的问题,请参考以下文章

mongo数据更新

使用官方 C# 驱动程序在 Mongo DB 中进行更新插入

Spring Boot Mongo Upsert 数组中的元素

ThinkPHP Mongo驱动update方法支持upsert参数

mongo更新的基本方法

mongo virtual