【问题标题】:Got invalid UTF-8 value serializing '�8' during MongoDB bulk write在 MongoDB 批量写入期间获得无效的 UTF-8 值序列化“�8”
【发布时间】:2018-09-09 13:48:47
【问题描述】:

我正在尝试将相对大量的数据存储到 MongoDB 中,使用 BulkWrite 进行多次插入。数据来自外部资源,所以我无法完全控制它的内容。单次批量操作的数据记录量可达15k甚至更多。这是我的代码的一部分:

$bulk = new BulkWrite();
foreach ($data as $id => $item) {
    $bulk->update(
        ['id' => $item['id']],
        $item,
        ['upsert' => true]
    );
}

try {
    $result = $mongo->getManager()->executeBulkWrite(
        'db.collection',
        $bulk,
        new WriteConcern(WriteConcern::MAJORITY)
    );
} catch (\MongoDB\Driver\Exception\UnexpectedValueException $e) {
    // we have a problem here
}

我有时会遇到这样的异常:

[MongoDB\Driver\Exception\UnexpectedValueException] 得到无效的 UTF-8 值序列化 '�8'

我不想过滤所有这些数据,因为它会影响性能。是否可以获得发生此异常的确切记录?据我所知,UnexpectedValueException 对象不提供此数据,它之前的异常也是UnexpectedValueException

【问题讨论】:

  • 嗯我对MongoDB了解不多,但也许是排序规则的问题?有些字符仅存在于 utf8mb4 中(每个字符 4 个字节),例如啤酒杯。
  • @Blackbam 感谢您的关注,但问题是我无法从整个插入的列表中精确检测到该符号所在的确切数据记录。但我从来不知道啤酒杯,这很有趣:)
  • 谢谢@Martin,我会检查的。

标签: php mongodb bulkinsert bulkupdate


【解决方案1】:

我找到的唯一解决方案是使用手动 BSON 编码方法调用添加 try/catch 块。遗憾的是,bson 值不能用作批量更新/插入操作的输入。所以,这个\MongoDB\BSON\fromPHP 调用是多余的,但是它可以检测“坏”记录。代码如下:

$bulk = new BulkWrite();
foreach ($data as $id => $item) {
    try {
        $bson = \MongoDB\BSON\fromPHP($item);
    } catch (UnexpectedValueException $e) {
        foreach ($item as $key => $value) {
            if (is_string($value)) {
                $item[$key] = mb_convert_encoding($value, 'UTF-8', 'UTF-8');
            } else {
                $item[$key] = $value;
            }
        }
    }

    $bulk->update(
        ['id' => $item['id']],
        $item,
        ['upsert' => true]
    );
}   

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-29
    • 2015-02-06
    • 1970-01-01
    • 2020-09-15
    • 1970-01-01
    相关资源
    最近更新 更多