从 Mongo shell 返回 BulkWriteError

Get back BulkWriteError from the Mongo shell

我想在执行 bulk.execute() 时将 writeErrors 文档存储到 MongoDB 中的另一个集合中。我基本上是在做批量操作 insert/update,但想在批量操作的同时将所有错误捕获到另一个集合中。

我可以看到BulkWriteError对象在Mongo-Shell中返回,我还可以看到对象中的writeErrors数组。但是我怎样才能捕捉到它呢?

I can see the BulkWriteError object is returned in Mongo-Shell

返回。这是一个 raised 异常。你需要一个 try...catch 块来取回它:

> bulk = db.w.initializeUnorderedBulkOp();
> bulk.insert({_id:1})
> bulk.insert({_id:1})
> try { result = bulk.execute() } catch(e) { err = e }

> err
BulkWriteError({
    "writeErrors" : [
        {
            "index" : 1,
            "code" : 11000,
            "errmsg" : "E11000 duplicate key error index: test.w.$_id_ dup key: { : 1.0 }",
            "op" : {
                "_id" : 1
            }
        }
    ],
    "writeConcernErrors" : [ ],
    "nInserted" : 1,
    "nUpserted" : 0,
    "nMatched" : 0,
    "nModified" : 0,
    "nRemoved" : 0,
    "upserted" : [ ]
})

令人惊讶的是,将 BulkWriteError 存储在集合中是相当痛苦的。一种简单的方法(虽然不一定是一种优雅的方法)是解析错误的 JSON 表示以取回您感兴趣的字段。

> db.errlog.insert(JSON.parse(err.tojson()).writeErrors)
//                 ^^^^^^^^^^^^^^^^^^^^^^^^
//      parse the JSON representation of `BulkWriteError`

这样,您将获得写入错误数组,insert 将愉快地存储在集合中:

> db.errlog.find().pretty()
{
    "_id" : ObjectId("55619737c0c8238aef6e21c5"),
    "index" : 0,
    "code" : 11000,
    "errmsg" : "E11000 duplicate key error index: test.w.$_id_ dup key: { : 1.0 }",
    "op" : {
        "_id" : 1
    }
}

根据https://github.com/mongodb/mongo/blob/master/src/mongo/shell/bulk_api.js(第363行):

// Bulk errors are basically bulk results with additional error information
BulkWriteResult.apply(this, arguments);

所以你可以使用BulkWriteResult.getWriteErrors()方法。

try {
    bulk.execute();
    ...
} catch(err) {
    if ("name" in err && err.name == 'BulkWriteError') {
        var wErrors = err.getWriteErrors();
        wErrors.forEach(function(doc){
            db.errlog.insert(doc);
        });
    }
}