我正在尝试将多个CSV导入并合并到mongo中,但是文档会被替换而不是合并。
例如,如果我有one.csv:
key1, first column, second column
和two.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
答案 0 :(得分:3)
这就是mongoimport
的工作方式。合并导入现有new feature request,但是现在,您必须编写自己的导入来提供合并行为。
答案 1 :(得分:3)
交叉收集解决方法: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}})})
答案 2 :(得分:1)
这是正确的,mongoimport --upsert更新完整文档。 您可以通过导入临时集合并使用以下Gist来实现目标。
将脚本加载到Mongo Shell并运行:
mergeCollections("srcCollectionName", "destCollectionName", {}, ["thirdColl"]);
答案 3 :(得分:0)
我遇到了一个非常类似的问题。 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()})'
在您的情况下,您必须首先通过管道jline-csv2jl
将csv转换为JSON行。这会将每个CSV行转换为一个字典,其名称取自标题。
我已将此示例添加到手册中:https://github.com/bitdivine/jline/blob/master/bin/foreach.md
我还没有将jline用于承诺,但到目前为止还不错。
免责声明:我是jline的作者。