将mongo查询的输出重定向到csv文件

时间:2013-01-23 11:12:17

标签: mongodb mongodb-.net-driver mongodb-query

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

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

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

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

感谢您的帮助:)

8 个答案:

答案 0 :(得分:145)

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

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

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

这我只是将查询传递给stdout

mongo test export.js > out.csv

其中test是我使用的数据库的名称。

答案 1 :(得分:79)

Mongo的内置导出工作正常,除非你想要任何数据操作,如格式日期,隐藏数据类型等。

以下命令可作为魅力。

mongoexport -h localhost -d databse -c collection --csv 
--fields erpNum,orderId,time,status 
-q '{"time":{"$gt":1438275600000}, "status":{"$ne" :"Cancelled"}}' 
--out report.csv

答案 2 :(得分: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() +"\"")

}

将其保存在文件中,例如&#34; export.js&#34;。运行以下命令:

mongo <host>/<dbname> -u <username> -p <password> export.js > out.csv

答案 3 :(得分:5)

看一看 this

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

答案 4 :(得分:5)

扩展其他答案:

我发现@ 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

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

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

答案 5 :(得分:1)

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

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

答案 6 :(得分: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'))

答案 7 :(得分: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