在现有文档中插入数组

时间:2015-07-07 19:17:03

标签: javascript node.js mongodb mongodb-query

我有这样的文件:

_id: ObjectId("559c1d2ad8291bc9368b4568")
 tablename: "IWEO_IWBB"
 out_user: "pb"
 out_email: "email"
 out_date: "15.05.2015"

并希望像这样添加数组:

"inventar": [
    {
        "ean": "2",
        "name": "name2",
        "runtime": "0",
        "art": "null",
        "marker": "null",
        "stammkost": "null",
        "accepted": "0"
    },
    {
        "ean": "1",
        "name": "name1",
        "runtime": "0",
        "art": "null",
        "marker": "null",
        "stammkost": "null",
        "accepted": "0"
    }
],

在我的旧PHP-Server中,我使用下面的代码插入它。 正确的命令是"更新"。在node.js中,它似乎是另一个命令。

foreach($jArray as $value){ 
    //$uuid = uniqid('', true);
    $tablename = $value['tablename'];
    $ean = $value["ean"];
    $runtime = $value["runtime"];
    $art = $value["art"];
    $marker = $value["marker"];
    $stammkost = $value["stammkost"];
    $new_data = array(
        //array (
        'ean' => $ean,
        'runtime' => $runtime,
        'art' => $art,
        'marker' => $marker,
        'stammkost' => $stammkost,
        'accepted' => '0'
        //)
    );
    try {
        $collection->update(array("tablename"=>$tablename),array('$push' => array("inventar" => $new_data)));
        echo json_encode($collection);
    }
    catch ( MongoConnectionException $e ) {
        echo '<p>Update failed</p>';
        exit();
    }           
}

在我的新node.js中,我使用下面的代码:

tables.forEach(function(table) {
var tablename = table.tablename;
var name = table.name ;
var ean = table.ean;
var runtime= table.runtime;
var art = table.art;
var marker = table.marker;
var stammkost = table.stammkost;
console.log(tablename+" "+ean+" "+name+" "+runtime+" "+art+" "+marker+" "+stammkost);
    OutAccept.update(function (err, data) {
    if (err) console.log(err);
    else {
    console.log(data);
    }
    });
    response.end();
    //}
    });

});

控制台中的输出是:

IWEO_IWBB_01062015 1 name1 11337 A null null
{ ok: 0, n: 0, nModified: 0 }
IWEO_IWBB_01062015 2 name2 A null null
{ ok: 0, n: 0, nModified: 0 }

为什么没有更新/插入?这是错误的命令?

1 个答案:

答案 0 :(得分:1)

您的代码中存在一些问题。首先要注意的是,您现在正在“异步”环境中运行,并且需要改变对如何执行某些操作的思考。

您以前的PHP代码是“阻塞”,这意味着在继续下一行代码之前必须完成每行代码。这包括等待数据库服务器执行更新并返回响应。

您不能使用基本控制循环,其中包含异步执行的函数。相反,一旦异步函数“update”实际返回结果,您需要能够调用循环的下一次迭代(或者至少表示单次迭代完成的信号)。

这里的第二点是“没有更新”,因为你没有告诉函数要更新什么或者用匹配文档更新什么。

以下内容类似于您原来的PHP列表,但针对“异步”方法进行了调整,也使用async.eachSeries进行async库中的循环控制:

async.eachSeries(
    tables,
    function(table,callback) {
        var tablename  = table.tablename;
        delete table.tablename;   // just remove the key rather than re-construct
        OutAccept.update(
            { "tablename": tablename },
            { "$push": { "inventar": table } },
            function(err,numAffected) {
                console.log( numAfftected ); // tells you how many are updated or nothing
                callback(err)
            }
        );
    },
    function(err) {
       // comes here on completion of all array items
    }
);

.findOneAndUpdate()命令仅返回已修改的文档,并且仅当您使用{ "new": true }

请求修改时才进行修改
async.eachSeries(
    tables,
    function(table,callback) {
        var tablename  = table.tablename;
        delete table.tablename;
        OutAccept.findOneAndUpdate(
            { "tablename": tablename },
            { "$push": { "inventar": table } },
            { "new": true },
            function(err,doc) {
                console.log( doc ); // shows the modified document
                callback(err)
            }
        );
    },
    function(err) {
       // comes here on completion of all array items
    }
);

如果您想一次添加多个数组元素,或者如果您在数组中直接使用单个元素,则使用$each修饰符$push

var inventor =  [
    {
        "ean": "2",
        "name": "name2",
        "runtime": "0",
        "art": "null",
        "marker": "null",
        "stammkost": "null",
        "accepted": "0"
    },
    {
        "ean": "1",
        "name": "name1",
        "runtime": "0",
        "art": "null",
        "marker": "null",
        "stammkost": "null",
        "accepted": "0"
    }
];


OutAccept.update(
    { "tablename": tablename },
    { "$push": { "inventar": { "$each": inventar } } },
    function(err,numAffected) {
       // work in here
    }
);