Ruby MongodB – 在处理多个集合时提高速度
我正在使用MongoDB和
Ruby使用mongo gem.
我有以下场景: >对于集合中的每个文档,请说出coll1,查看key1和key2 MongoDB的一般准则是处理应用程序代码中的交叉收集操作. 所以我做了以下事情: client = Mongo::Client.new([ '127.0.0.1:27017' ],:database => some_db,:server_selection_timeout => 5) cursor = client[:coll1].find({},{ :projection => {:_id => 0} }) # exclude _id cursor.each do |doc| doc_coll2 = client[:coll2].find('$and' => [{:key1 => doc[:key1]},{:key2 => doc[:key2] }]).limit(1).first # no find_one method if(doc_coll2 && doc[:key3]) doc_coll2[:key3] = doc[:key3] doc_coll2.delete(:_id) # remove key :_id client[:coll3].insert_one(doc_coll2) end end 这可行,但是完成这项工作需要花费大量时间 – 收集coll1中的每个文档大约250ms或者大约15000条记录的3600s(1小时),这看起来很多,这可能与一次读取一个文档有关,检查应用程序代码,然后一次将一个文档写回新的集合. 有没有办法让这项操作更快完成?我正在做的方式甚至是正确的方法吗? 示例文档 > coll1 { "_id" : ObjectId("588610ead0ae360cb815e55f"),"key1" : "115384042","key2" : "276209","key3" : "10101122317876" } > coll2 { "_id" : ObjectId("788610ead0ae360def15e88e"),"key4" : 10,"key5" : 4,"key6" : 0,"key7" : "false","key8" : 0,"key9" : "false" } > coll3 { "_id" : ObjectId("788610ead0ae360def15e88e"),"key3" : "10101122317876","key9" : "false" } 解决方法
解决方案是使用聚合,并在一个查询中执行此操作:
>使用$lookup在key1字段上执行连接 所以查询将是: db.coll1.aggregate([ { "$lookup": { "from": "coll2","localField": "key1","foreignField": "key1","as": "coll2_doc" }},{ "$unwind": "$coll2_doc" },{ "$redact": { "$cond": [ { "$eq": [ "$key2","$coll2_doc.key2" ] },"$$KEEP","$$PRUNE" ] }},{ $project: { key1: 1,key2: 1,key3: 1,key4: "$coll2_doc.key4",key5: "$coll2_doc.key5",key6: "$coll2_doc.key6",key7: "$coll2_doc.key7",key8: "$coll2_doc.key8",key9: "$coll2_doc.key9",} },{$out: "coll3"} ],{allowDiskUse: true} ); 和db.coll3.find()将返回 { "_id" : ObjectId("588610ead0ae360cb815e55f"),"key9" : "false" } 编辑:MongoDB 3.4解决方案 如果您不想在$project阶段指定所有键,则可以利用$addFields和$replaceRoot,MongoDB 3.4中引入的两个新运算符 查询将变为: db.coll1.aggregate([ { "$lookup": { "from": "coll2",{$addFields: {"coll2_doc.key3": "$key3" }},{$replaceRoot: {newRoot: "$coll2_doc"}},{allowDiskUse: true}) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |