Я использую MongoDB 2.2.2 для 32-разрядной машины Windows7. У меня есть сложный запрос агрегирования в файле .js. Мне нужно выполнить этот файл в оболочке и направить вывод в файл CSV. Я гарантирую, что запрос вернет "плоский" json (без вложенных ключей), поэтому он по своей сути может быть преобразован в аккуратный csv.
Я знаю про load()
и eval()
. eval()
требует, чтобы я вставил весь запрос в оболочку и разрешает только printjson()
внутри скрипта, а мне нужен csv. И, второй способ: .. load()
Он выводит результат на экран, и снова в формате json.
Есть ли способ, которым Mongo может выполнить это преобразование из json в csv? (Мне нужен файл csv для подготовки диаграмм по данным). Я думаю:
1. Либо у mongo есть встроенная команда для этого, которую я не могу найти прямо сейчас.
2. Монго не может сделать это за меня; В лучшем случае я могу отправить вывод json в файл, который затем мне нужно будет сам преобразовать в csv.
3. Mongo может отправлять выходные данные json во временную коллекцию, содержимое которой может быть легко mongoexported
преобразовано в формат csv. Но я думаю, что только запросы map-reduce поддерживают выходные коллекции. Это правильно? Мне он нужен для запроса агрегирования.
Спасибо за любую помощь :)
источник
Ответы:
Я знаю, что это старый вопрос, но я потратил час, пытаясь экспортировать сложный запрос в csv, и хотел поделиться своими мыслями. Сначала я не мог заставить работать ни один из конвертеров json в csv (хотя этот выглядел многообещающим). В итоге я написал вручную файл csv в моем сценарии mongo.
Это простая версия, но по сути то, что я сделал:
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
имя используемой мной базы данных.источник
use <database>
в начало скрипта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
источник
--type=csv
вместо--csv
.Расширение других ответов:
Я нашел ответ @ GEverding самым гибким. Он также работает с агрегацией:
test_db.js
print("name,email"); db.users.aggregate([ { $match: {} } ]).forEach(function(user) { print(user.name+","+user.email); } });
Выполните следующую команду, чтобы экспортировать результаты:
К сожалению, он добавляет дополнительный текст в файл CSV, который требует обработки файла, прежде чем мы сможем его использовать:
MongoDB shell version: 3.2.10 connecting to: test_db
Но мы можем заставить оболочку mongo перестать выплевывать эти комментарии и печатать только то, что мы просили, передав
--quiet
флагисточник
Вот что можно попробовать:
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 в файл. Нет поддержки вывода csv из оболочки mongos. Вам придется написать javascript самостоятельно или использовать один из множества доступных конвертеров. Например, Google "конвертирует 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 следующим образом:источник
Я использую следующую технику. Это позволяет легко синхронизировать имена столбцов с содержимым:
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
опция отключит только журналы, связанные с подключением. Не все журналы монго. В таком случае нам может потребоваться вручную отфильтровать ненужные строки. Пример для 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
.источник