当我们使用 NODE + MONGO做网页应用的时候,需要对数据进行不同表的搬运,且根据前端发起的请求,想要对搬运的数据做一定的处理。
这个时候我们就犯难了,明明只是mongo到mongo的一个数据搬运,可是几十万的搬进node里面,处理过后再存进mongo,node v8 内存急剧上升,按秒爆给你看,好不容易用个子进程加控制并发,勉勉强强可以应付至少这个批量动作不干扰到主进程的应用。可是总觉得成了一个岌岌可危的功能,随时可能要担心数据。
经过不懈的努力,我终于找到办法了 T——T
英文如此之差的我竟然看懂了好几篇网页
首先,使用存储过程进行跨库的获取和存入数据,就是写一个js脚本命名为carry.js,如下
<pre class="public-DraftStyleDefault-pre" data-offset-key="fctjd-0-0" style="margin: 1.4em 0px; padding: 0.88889em; font-size: 0.9em; word-break: normal; overflow-wrap: normal; white-space: pre; overflow: auto; background: rgb(246, 246, 246); border-radius: 4px; color: rgb(26, 26, 26); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">
<pre class="Editable-styled" data-block="true" data-editor="6a5oh" data-offset-key="fctjd-0-0" style="margin: 0px; padding: 0px; font-size: 0.9em; word-break: normal; overflow-wrap: normal; white-space: pre; overflow: initial; background: rgb(246, 246, 246); border-radius: 0px;">
// 跨库搬运得情况下,连接第一个库 var db = connect('mongodb://127.0.0.1:27017/firstdb'); // 连接第二个库 var nextdb = connect('mongodb://127.0.0.1:27017/seconddb'); // 将符合要求的数据找出,赋值给一个变量 var datas = db.first_collection.find({}).toArray(); // 将数据生成进入目标表 nextdb.second_collection.insert(datas); // 完成后打印成功 print("success")
</pre>
</pre>
执行一下
<pre class="public-DraftStyleDefault-pre" data-offset-key="1m2q-0-0" style="margin: 1.4em 0px; padding: 0.88889em; font-size: 0.9em; word-break: normal; overflow-wrap: normal; white-space: pre; overflow: auto; background: rgb(246, 246, 246); border-radius: 4px; color: rgb(26, 26, 26); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">
<pre class="Editable-styled" data-block="true" data-editor="6a5oh" data-offset-key="1m2q-0-0" style="margin: 0px; padding: 0px; font-size: 0.9em; word-break: normal; overflow-wrap: normal; white-space: pre; overflow: initial; background: rgb(246, 246, 246); border-radius: 0px;">
mongo 127.0.0.1:27017/firstdb ./carry.js
</pre>
</pre>
很快我们可以得到执行的结果
image我们去查一下数据表,看看是否搬运成功
image然后说过支持传参的嘛,现在我假设这次搬运到B表的数据是A表中name为‘zhang’的数据,可是这个name的值又是一个变量,需要从外部传进去。
<pre class="public-DraftStyleDefault-pre" data-offset-key="9ad7c-0-0" style="margin: 1.4em 0px; padding: 0.88889em; font-size: 0.9em; word-break: normal; overflow-wrap: normal; white-space: pre; overflow: auto; background: rgb(246, 246, 246); border-radius: 4px; color: rgb(26, 26, 26); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">
<pre class="Editable-styled" data-block="true" data-editor="6a5oh" data-offset-key="9ad7c-0-0" style="margin: 0px; padding: 0px; font-size: 0.9em; word-break: normal; overflow-wrap: normal; white-space: pre; overflow: initial; background: rgb(246, 246, 246); border-radius: 0px;">
var db = connect('mongodb://127.0.0.1:27017/firstdb'); var nextdb = connect('mongodb://127.0.0.1:27017/seconddb'); var datas = db.first_collection.find({name: carry_name}).toArray(); nextdb.second_collection.insert(datas); print("success")
</pre>
</pre>
可是看到,我们的脚本已经添加了carry_name这个参数,这样传进入
<pre class="public-DraftStyleDefault-pre" data-offset-key="d3bvm-0-0" style="margin: 1.4em 0px; padding: 0.88889em; font-size: 0.9em; word-break: normal; overflow-wrap: normal; white-space: pre; overflow: auto; background: rgb(246, 246, 246); border-radius: 4px; color: rgb(26, 26, 26); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">
<pre class="Editable-styled" data-block="true" data-editor="6a5oh" data-offset-key="d3bvm-0-0" style="margin: 0px; padding: 0px; font-size: 0.9em; word-break: normal; overflow-wrap: normal; white-space: pre; overflow: initial; background: rgb(246, 246, 246); border-radius: 0px;">
mongo 127.0.0.1:27017/firstdb --eval "var carry_name='zhang'" ./carry.js
</pre>
</pre>
再次执行
image最后通过NODE执行这句话
<pre class="public-DraftStyleDefault-pre" data-offset-key="dmoak-0-0" style="margin: 1.4em 0px; padding: 0.88889em; font-size: 0.9em; word-break: normal; overflow-wrap: normal; white-space: pre; overflow: auto; background: rgb(246, 246, 246); border-radius: 4px; color: rgb(26, 26, 26); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">
<pre class="Editable-styled" data-block="true" data-editor="6a5oh" data-offset-key="dmoak-0-0" style="margin: 0px; padding: 0px; font-size: 0.9em; word-break: normal; overflow-wrap: normal; white-space: pre; overflow: initial; background: rgb(246, 246, 246); border-radius: 0px;">
var exec = require('child_process').exec; function funName() { exec('mongo 127.0.0.1:27017/firstdb --eval "var carry_name='zhang'" ./carry.js', function(err, result) { console.log("finish"); } } tips:如果是参数过多的情况下,可以成立一个任务表,在node里先在任务表里生成一条数据,数据里包括所需要的参数,然后通过命令的方式将任务数据的_id以参数的形式传进去,然后在再存储过程文件中找任务数据中的值为变量。
</pre>
</pre>
好了,一个随时搞崩溃系统的批量数据搬运,就让强大的MONGO数据库去做吧,NODE就好好发挥自己的强项高并发I/O就不去参与了。
<pre class="public-DraftStyleDefault-pre" data-offset-key="d5uj7-0-0" style="margin: 1.4em 0px; padding: 0.88889em; font-size: 0.9em; word-break: normal; overflow-wrap: normal; white-space: pre; overflow: auto; background: rgb(246, 246, 246); border-radius: 4px; color: rgb(26, 26, 26); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">
<pre class="Editable-styled" data-block="true" data-editor="6a5oh" data-offset-key="d5uj7-0-0" style="margin: 0px; padding: 0px; font-size: 0.9em; word-break: normal; overflow-wrap: normal; white-space: pre; overflow: initial; background: rgb(246, 246, 246); border-radius: 0px;">
参考文献:
01. https://stackoverflow.com/questions/22503984/command-line-argument-to-a-javascript-file-that-works-o
</pre>
</pre>
网友评论