我在 32 位 Windows7 机器上使用 MongoDB 2.2.2。我在 .js 文件中有一个复杂的聚合查询。我需要在 shell 上执行此文件并将输出定向到 CSV 文件。我确保查询返回一个“平面”json(无嵌套键),因此它本质上可以转换为整洁的 csv。
我知道
load()
和 eval()
。 eval()
要求我将整个查询粘贴到 shell 中,并且只允许在脚本中使用 printjson()
,而我需要 csv。并且,第二种方式:load()
..它将输出打印在屏幕上,并再次以 json 格式打印。mongoexported
转换为csv格式。但我认为只有映射减少查询支持输出集合。是这样吗?我需要它来进行聚合查询。
感谢您的帮助:)
我知道这个问题很老了,但我花了一个小时尝试将复杂的查询导出到 csv,我想分享我的想法。 首先,我无法让任何 json 到 csv 转换器工作(尽管 this 看起来很有希望)。 我最终做的是在我的 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
是我使用的数据库的名称。
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
扩展其他答案:
我发现@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
您可以尝试以下方法:
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
看看 这个
用于从 mongo shell 输出到文件。 不支持从 mongos shell 输出 csv。您必须自己编写 JavaScript 或使用众多可用转换器之一。例如,谷歌“将 json 转换为 csv”。
只是在这里权衡我一直在使用的一个很好的解决方案。这类似于上面的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
我使用以下技术。它可以轻松保持列名称与内容同步:
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'))
在远程服务器中执行脚本时。 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://learn.microsoft.com/en-us/windows-server/administration/windows-commands/findstr
Linux 版本将使用
grep
。
如果我想将查询结果转换成csv格式,并且有些数据字段是对象(不是单个字段),本身有逗号分隔多段数据?