Переспрямування виводу запиту mongo у файл CSV


85

Я використовую MongoDB 2.2.2 для 32-розрядної машини Windows7. У мене є складний запит агрегування у файлі .js. Мені потрібно виконати цей файл на оболонці та направити вихід у файл CSV. Я гарантую, що запит повертає "плоский" json (без вкладених ключів), тому він за своєю суттю може бути конвертований у акуратний csv.

Я знаю про load()та eval(). eval()вимагає від мене вставити весь запит у оболонку і дозволяє лише printjson()всередині сценарію, тоді як мені потрібен csv. І, другий спосіб: load()..Він друкує вихідні дані на екрані, і знову у форматі json.

Чи є спосіб, яким Монго може зробити це перетворення з json в csv? (Мені потрібен файл CSV для підготовки діаграм з даними). Я думаю:

1. Будь-який mongo має вбудовану команду для цього, яку я зараз не можу знайти.
2. Монго не може зробити це за мене; Я можу щонайбільше надіслати вихідні дані json у файл, який мені потім потрібно перетворити на CSV.
3. Mongo може надіслати вихідні дані json до тимчасової колекції, вміст якої може бути легко mongoexportedперенесено у формат CSV. Але я думаю, що лише запити зі зменшенням карти підтримують вихідні колекції. Це так? Він потрібен для запиту агрегації.

Дякуємо за будь-яку допомогу :)


1
Якщо це те, що ви часто робите, ви можете розглянути можливість самостійного написання EXE за допомогою .NET, python або NodeJs; кожен має власний драйвер, який полегшить виконання вашого коду та виведення бажаного результату.
WiredPrairie

Я маю на увазі відповідь Захарі на stackoverflow.com/questions/4130849/… і я можу конвертувати з json в csv. Але як альтернативу, чи можу я вивести json у колекцію, а потім зробити монгоекспорт?
Aafreen Sheikh

Я рекомендую вам просто створити невеликий джгут, використовуючи Node і драйвер MongoDB для NodeJS, і тоді ви можете виконати будь-який код, який хочете. Ви отримаєте бажані результати дуже швидко, взагалі не потребуючи оболонки. Це було б дуже ремонтопридатним (і налагодженим).
WiredPrairie

Відповіді:


175

Я знаю, що це питання застаріле, але я витрачаю годину, намагаючись експортувати складний запит до csv, і я хотів поділитися своїми думками. По-перше, я не зміг змусити працювати жоден з перетворювачів json в csv (хоча цей виглядав багатообіцяючим). У підсумку я зробив ручний запис файлу CSV у моєму сценарії mongo.

Це проста версія, але по суті, що я зробив:

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ім'я бази даних, яку я використовую.


Як я можу вказати, в якому базі даних знаходиться колекція користувачів?
Нелу

2
@NeluMalancea перегляньте документи MongoDB, вони мають цю інформацію. Ви можете вказати БД, додавши use <database>вгорі сценарію
GEverding

2
Насправді, оскільки помічники оболонки, такі як "use <database>", не є javascript, вони заборонені. Див. Docs.mongodb.org/manual/tutorial/… . Натомість запустіть скрипт приблизно так: conn = new Mongo (); db = conn.getDB ('Ваше_дім'я_назви');
Steve Hansen Smythe

2
@NeluMalancea команда mongo приймає db-адресу (і користувач, передати, ...)
iwein

3
@NeluMalancea testв останній команді є ім'ям бази даних, просто замініть її на ім'я вашої бази даних.
Золтан

112

Вбудований експорт 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

17
Дякую тонна! Підказка: зараз це --type=csvзамість --csv.
січня

Обмеження монгоекспорту полягає в тому, що ви не можете маніпулювати полями. Ідентифікатор mongo експортується як ObjectId (mongidstring). Можливість експортувати результати зі сценарію оболонки mongo краще, якщо хтось хоче маніпулювати даними полів (наприклад, ObjectId (mongidstring) .toString ()).
Raj006

чи можу я робити операції агрегування?
Хенді Іраван,

Це рішення спрацювало. Але для Windows мені довелося внести дві поправки: мені просто знадобився подвійний апостроф ззовні та одинарні апострофи всередині, як -Q "{name: 'stackoverflow'}", також для вказування порту команда -p не працювала, я використовував - -порт 27000.
nurb

10

Розширення інших відповідей:

Я знайшов відповідь @ 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 перестати виплювати ці коментарі і надрукувати лише те, про що ми просили, передавши --quietпрапор

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

1
Редагувати його відповідь було б краще, ніж додати нову.
Ренато Назад

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

5

Погляньте на це

для виведення з оболонки mongo у файл. Немає підтримки для виведення csv з оболонки mongos. Вам доведеться написати javascript самостійно або скористатися одним із багатьох доступних конвертерів. Наприклад, Google "конвертує json в csv".


0

Просто зважуючи тут гарне рішення, яке я використовував. Це схоже на рішення 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.