103

我将 MongoDB 2.2.2 用于 32 位 Windows7 机器。我在 .js 文件中有一个复杂的聚合查询。我需要在 shell 上执行这个文件并将输出定向到 CSV 文件。我确保查询返回“平面”json(没有嵌套键),因此它本质上可以转换为整洁的 csv。

我知道load()eval()eval()要求我将整个查询粘贴到 shell 中,并且只允许printjson()在脚本内部,而我需要 csv。并且,第二种方式:load()..它在屏幕上打印输出,并再次以 json 格式打印。

Mongo 有没有办法从 json 到 csv 进行这种转换?(我需要 csv 文件来准备数据图表)。我在想:

1. mongo 都有一个我现在找不到的内置命令。
2. Mongo不能帮我做;我最多可以将 json 输出发送到一个文件,然后我需要自己将其转换为 csv。
3. Mongo 可以将 json 输出发送到一个临时集合,其中的内容可以很容易地mongoexported转换为 csv 格式。但我认为只有 map-reduce 查询支持输出集合。是对的吗?我需要它来进行聚合查询。

谢谢你的帮助 :)

4

8 回答 8

195

我知道这个问题很老,但我花了一个小时尝试将复杂的查询导出到 csv,我想分享我的想法。首先,我无法让任何 json 到 csv 转换器工作(尽管这个看起来很有希望)。我最终做的是在我的 mongo 脚本中手动编写 csv 文件。

这是一个简单的版本,但基本上是我所做的:

print("name,id,email");
db.User.find().forEach(function(user){
  print(user.name+","+user._id.valueOf()+","+user.email);
});

我只是将查询通过管道传输到标准输出

mongo test export.js > out.csv

test我使用的数据库的名称在哪里。

于 2013-08-18T18:46:39.133 回答
127

Mongo 的内置导出工作正常,除非您想要进行任何数据操作,如格式化日期、隐蔽数据类型等。

以下命令作为魅力。

    mongoexport -h localhost -d databse -c collection --type=csv 
    --fields erpNum,orderId,time,status 
    -q '{"time":{"$gt":1438275600000}, "status":{"$ne" :"Cancelled"}}' 
    --out report.csv
于 2015-09-07T03:29:44.607 回答
12

扩展其他答案:

我发现@GEverding 的回答最灵活。它也适用于聚合:

test_db.js

print("name,email");

db.users.aggregate([
    { $match: {} }
]).forEach(function(user) {
        print(user.name+","+user.email);
    }
});

执行以下命令导出结果:

mongo test_db < ./test_db.js >> ./test_db.csv

不幸的是,它在 CSV 文件中添加了额外的文本,这需要在我们使用它之前处理文件:

MongoDB shell version: 3.2.10 
connecting to: test_db

--quiet但是我们可以让 mongo shell 停止吐出这些评论,只通过传递标志来打印我们要求的内容

mongo --quiet test_db < ./test_db.js >> ./test_db.csv
于 2017-08-01T12:52:16.697 回答
6

您可以尝试以下方法:

print("id,name,startDate")
cursor = db.<collection_name>.find();
while (cursor.hasNext()) {
    jsonObject = cursor.next();
    print(jsonObject._id.valueOf() + "," + jsonObject.name + ",\"" + jsonObject.stateDate.toUTCString() +"\"")

}

将其保存在一个文件中,例如“export.js”。运行以下命令:

mongo <host>/<dbname> -u <username> -p <password> export.js > out.csv
于 2014-07-17T20:04:35.870 回答
5

看看 这个

用于从 mongo shell 输出到文件。不支持从 mongos shell 输出 csv。您必须自己编写 javascript 或使用可用的众多转换器之一。例如,谷歌“将 json 转换为 csv”。

于 2013-01-23T11:38:52.087 回答
1

在这里权衡一下我一直在使用的一个很好的解决方案。这类似于上面Lucky Soni 的解决方案,因为它支持聚合,但不需要对字段名称进行硬编码。

cursor = db.<collection_name>.<my_query_with_aggregation>;

headerPrinted = false;
while (cursor.hasNext()) {
    item = cursor.next();
    
    if (!headerPrinted) {
        print(Object.keys(item).join(','));
        headerPrinted = true;
    }

    line = Object
        .keys(item)
        .map(function(prop) {
            return '"' + item[prop] + '"';
        })
        .join(',');
    print(line);
}

将其保存为.js文件,在这种情况下,我们将调用它example.js并使用 mongo 命令行运行它,如下所示:

mongo <database_name> example.js --quiet > example.csv
于 2020-10-28T18:42:24.560 回答
0

我使用以下技术。它可以很容易地使列名与内容保持同步:

var cursor = db.getCollection('Employees.Details').find({})

var header = []
var rows = []

var firstRow = true
cursor.forEach((doc) => 
{
    var cells = []
    
    if (firstRow) header.push("employee_number")
    cells.push(doc.EmpNum.valueOf())

    if (firstRow) header.push("name")
    cells.push(doc.FullName.valueOf())    

    if (firstRow) header.push("dob")
    cells.push(doc.DateOfBirth.valueOf())   
    
    row = cells.join(',')
    rows.push(row)    

    firstRow =  false
})

print(header.join(','))
print(rows.join('\n'))
于 2020-11-26T12:28:15.983 回答
0

在远程服务器中执行脚本时。Mongo 将添加它自己的日志输出,我们可能想从我们的文件中省略它。 --quiet选项只会禁用连接相关的日志。不是所有的 mongo 日志。在这种情况下,我们可能需要手动过滤掉不需要的行。基于 Windows 的示例:

mongo dbname --username userName --password password --host replicaset/ip:port --quiet printDataToCsv.js | findstr /v "NETWORK" > data.csv

这将通过管道输出脚本并用于findstr过滤掉其中包含 NETWORK 字符串的任何行。有关 findstr 的更多信息:https ://docs.microsoft.com/en-us/windows-server/administration/windows-commands/findstr

Linux 版本将使用grep.

于 2020-12-23T12:34:35.870 回答