Mongoimport для слияния / удаления полей


Я пытаюсь импортировать и объединить несколько CSV в mongo, однако документы заменяются, а не объединяются.

Например, если он у меня есть.csv:
key1, first column, second column

И два.csv:

key1, third column

Я хотел бы закончить словами:

key1, first column, second column, third column

Но вместо этого я получаю:

key1,third column

В настоящее время я использую:

mongoimport.exe --ftype csv --file first.csv --fields key,firstColumn,secondColumn
mongoimport.exe --ftype csv --file second.csv --fields key,thirdColumn --upsert --upsertFields key1
4 3

4 ответа:

Именно так и работает mongoimport. Существует существующий запрос новой функции для импорта слиянием, но пока вам придется написать свой собственный импорт, чтобы обеспечить поведение слияния.

Кросс-коллекция обходной путь: метод forEach может быть запущен для фиктивной коллекции и результирующих объектов doc, используемых для поиска / обновления нужной коллекции:

mongoimport.exe --collection mycoll --ftype csv --file first.csv --fields key,firstColumn,secondColumn
mongoimport.exe --collection dummy --ftype csv --file second.csv --fields key,third

db.dummy.find().forEach(function(doc) {db.mycoll.update({key:doc.key},{$set:{thirdcol:doc.third}})})

Правильно, mongoimport -- upsert обновляет полные документы. Вы можете достичь своей цели, импортировав во временную коллекцию и используя следующий Gist.

Загрузите скрипт в оболочку Mongo и выполните:

mergeCollections("srcCollectionName", "destCollectionName", {}, ["thirdColl"]); 

У меня только что была очень похожая проблема. Существует модуль узла для mongo и jline - это мой инструмент узла командной строки для потоковой обработки JSON-строк. Итак:

echo '{"page":"index.html","hour":"2015-09-18T21:00:00Z","visitors":1001}' |\
jline-foreach \
    'beg::dp=require("bluebird").promisifyAll(require("mongodb").MongoClient).connectAsync("mongodb://localhost:27017/nginx")' \
    'dp.then(function(db){
       updates = {}
       updates["visitors.hour."+record.hour] = record.visitors;
       db.collection("pagestats").update({_id:record.page},{$set:updates},{upsert:true});});' \
    'end::dp.then(function(db){db.close()})'

В вашем случае вам придется сначала преобразовать строки csv в JSON, пропустив их через jline-csv2jl. Это преобразует каждую строку CSV в словарь с именами, взятыми из заголовка.

Я добавил этот пример в руководство: https://github.com/bitdivine/jline/blob/master/bin/foreach.md

Я не использовал джлайн много обещает, но пока все в порядке.

Отказ от ответственности: я являюсь автором jline.