Переспрямування виводу запиту 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.