MongoDB,将元素数据类型从数字字符串转换为数字以进行大集合(3kk)

问题描述 投票:0回答:2

我有一个很大的3kk mongodb集合,需要将一个元素从数字字符串转换为数字。

我正在使用适用于小型100k元素集合的mongo-shell脚本,请参见下面的脚本:

db.SurName.find().forEach(function(tmp){
    tmp.NUMBER = parseInt(tmp.NUMBER);
    db.SurName.save(tmp);
})

但是经过十几分钟的工作,我遇到了一个错误(即使集合较小,如1kk,也会发生错误:

MongoDB Enterprise Test-shard-0:PRIMARY> db.SurName.find().forEach(function(tmp){
...         tmp.NUMBER = parseInt(tmp.NUMBER);
... db.SurName.save(tmp);
...     })
2020-01-18T16:59:21.173+0100 E  QUERY    [js] Error: command failed: {
        "operationTime" : Timestamp(1579363161, 14),
        "ok" : 0,
        "errmsg" : "cursor id 4811116025485863761 not found",
        "code" : 43,
        "codeName" : "CursorNotFound",
        "$clusterTime" : {
                "clusterTime" : Timestamp(1579363161, 14),
                "signature" : {
                        "hash" : BinData(0,"EemWWenbArSdh4dTFa0aNcfAPms="),
                        "keyId" : NumberLong("6748451824648323073")
                }
        }
} : getMore command failed: {
        "operationTime" : Timestamp(1579363161, 14),
        "ok" : 0,
        "errmsg" : "cursor id 4811116025485863761 not found",
        "code" : 43,
        "codeName" : "CursorNotFound",
        "$clusterTime" : {
                "clusterTime" : Timestamp(1579363161, 14),
                "signature" : {
                        "hash" : BinData(0,"EemWWenbArSdh4dTFa0aNcfAPms="),
                        "keyId" : NumberLong("6748451824648323073")
                }
        }
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
doassert@src/mongo/shell/assert.js:18:14
_assertCommandWorked@src/mongo/shell/assert.js:583:17
assert.commandWorked@src/mongo/shell/assert.js:673:16
DBCommandCursor.prototype._runGetMoreCommand@src/mongo/shell/query.js:802:5
DBCommandCursor.prototype._hasNextUsingCommands@src/mongo/shell/query.js:832:9
DBCommandCursor.prototype.hasNext@src/mongo/shell/query.js:840:16
DBQuery.prototype.hasNext@src/mongo/shell/query.js:288:13
DBQuery.prototype.forEach@src/mongo/shell/query.js:493:12
@(shell):1:1

是否有办法更好/正确地做到这一点?

编辑:obj模式:

{"_id":{"$oid":"5e241b98c7cab1382c7c9d95"},
"SURNAME":"KOWALSKA",
"SEX":"KOBIETA",
"TERYT":"0201011",
"NUMBER":"51",
"COMMUNES":"BOLESŁAWIEC",
"COUNTIES":"BOLESŁAWIECKI",
"PROVINCES":"DOLNOŚLĄSKIE"
}
json mongodb mongo-shell
2个回答
1
投票

最佳和快速的解决方案是将mongodb aggregation$out运算符一起使用。

相当于:

insert into new_table
select * from old_table

我们用NUMBER(MongoDB版本> = 4.0)运算符转换$toInt字段,并将文档存储在SurName2集合中。完成后,我们只需删除旧集合并将SurName2集合重命名为SurName

db.SurName.aggregate([
  {$addFields:{
    NUMBER : {$toInt:"$NUMBER"}
  }},
  {$out: "SurName2"}
])

一旦您检查了一切都很好,请执行以下语句:

db.SurName.drop()
db.SurName2.renameCollection("SurName")

0
投票

** 编辑-开始 **

使用谷歌搜索“未找到光标ID代码43”,得到了这个答案:https://stackoverflow.com/a/51602507/2279082

** 编辑-结束 **

我没有您的数据集,所以我无法很好地测试我的答案。话虽如此,您可以尝试Update特定字段(请参阅有关文档中的更新:db.collection.update

所以您的脚本将如下所示:

db.SurName.find({}, {NUMBER: 1}).forEach(function(tmp){
    db.SurName.update({_id: tmp._id}, {$set: {NUMBER: parseInt(tmp.NUMBER)}});
})

让我知道它是否有帮助或是否需要编辑

© www.soinside.com 2019 - 2024. All rights reserved.