在mongo和upsert中更新数组

时间:2014-10-12 00:35:12

标签: arrays mongodb mongoose mongodb-query

我尝试更新文档中的数组并且它可以正常工作,但是当我想添加带有upsert的新元素时,如何运行错误。我一直在谷歌搜索几个小时和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:位置运算符未找到查询所需的匹配项。未更新的更新:提供商。$。名称

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

由于

1 个答案:

答案 0 :(得分: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
            }
        }
    });
}