使用 mongoimport 将 csv 数据作为数组导入 mongodb

tar*_*ggi 6 mongodb mongoimport

我一直在尝试使用 mongoimport 将 csv 数据导入 mongodb。合集是这样的:

{
id:"122234343",
name: "name1",
children: ["222334444","333344444"]
}
Run Code Online (Sandbox Code Playgroud)

我尝试过的一种方法是创建 2 个 csv 文件 - 一个带有 id & name ,另一个带有 id, children(如果 id 有两个孩子,那么它将有两行)。使用 mongoimport 将数据导入两个不同的集合,然后在具有子数据的第二个集合中使用 foreach() 更新集合数据。

请建议有没有其他方法可以直接从 CSV 填充这个“子”数组?

Nei*_*unn 8

对我来说,解决如何格式化“CSV”的最简单方法mongoimport是简单地创建一个集合,然后使用mongoexport它来查看 CSV 格式应该是什么样子。

因此,从 shell 创建您的文档:

db.newcol.insert({
  id:"122234343",
  name: "name1",
  children: ["222334444","333344444"]
})
Run Code Online (Sandbox Code Playgroud)

然后退出shell并运行mongoexport

 mongoexport -d test -c testcol --fields id,name,children --type csv > out.csv
Run Code Online (Sandbox Code Playgroud)

这将显示输出为:

id,name,children
122234343,name1,"[""222334444"",""333344444""]"
Run Code Online (Sandbox Code Playgroud)

其中“数组”用“字符串”表示并使用""转义形式的引号。

现在是一个非常清楚的使用位置mongoimport,所以现在只需“导入”来测试:

mongoimport -d test -c newcol --headerline --type csv out.csv
Run Code Online (Sandbox Code Playgroud)

重新进入 shell 并查看新集合中的文档:

db.newcol.findOne()
{
        "_id" : ObjectId("59476924d6eb0b7d6ac37e02"),
        "id" : 122234343,
        "name" : "name1",
        "children" : "[\"222334444\",\"333344444\"]"
}
Run Code Online (Sandbox Code Playgroud)

所以一切都在那里,但是孩子们被列为“字符串”而不是数组。但这并不是真正的问题,因为我们已经导入了数据,现在只需要我们来实际转换它了:

var ops = [];
db.testcol.find({ "children": { "$type": 2} }).forEach(doc => {
  var children = doc.children.split(',').map( e => e.replace(/"|\[|\]|\\/gm,'').toString() );
  ops.push({
    "updateOne": {
      "filter": { "_id": doc._id },
      "update": { "$set": { "children": children } }
    }
  });

  if ( ops.length >= 1000 ) {
    db.newcol.bulkWrite(ops);
    ops = [];
  }             
});

if ( ops.length > 0 ) {
  db.newcol.bulkWrite(ops);
  ops = [];
}
Run Code Online (Sandbox Code Playgroud)

因此,这将通过$type查询运算符迭代任何导入到集合中的 BSON 类型为 2 的“字符串” 。

然后我们取字符串,将其拆分为一个数组并去除其他字符以仅保留您想要的值。

使用.bulkWrite()您以有效的方式提交这些更新,而不是为每个请求编写每个文档。它们实际上以 1000 个为一组发送到服务器。

最终结果是原始通缉形式的文件:

db.testcol.findOne()
{
        "_id" : ObjectId("5947652ccb237bd6e4e902a5"),
        "id" : "122234343",
        "name" : "name1",
        "children" : [
                "222334444",
                "333344444"
        ]
}
Run Code Online (Sandbox Code Playgroud)

这就是我关于如何制定 CSV 格式、导入它然后将数据“转换”为您需要的状态的“一步一步”。