【发布时间】:2019-07-25 12:36:20
【问题描述】:
我正在编写一个脚本,我需要从 mongodb 集合中获取数据,通过一些重命名和映射对其进行处理,然后将数据放到其他集合中。我在 expressjs 中使用这个脚本和用于 nodejs 的 mongodb-native 客户端。
这是我的所有运行函数的脚本
const syncCustomerWithCustomerv1 = function(params){
utils.connectDB().then((client) => {
Promise.map(aggregateDocumentsv1(client, params), function(cursor){
Promise.map(getCustomerDatav1(cursor), function(customer){
var hashedMap = makeHashedObjectv1(customer);
makeDatav1(client, customer, hashedMap).then((response)=> {
console.log("success");
}).catch((error) => {
console.log(error);
reject(error);
})
}, {concurrency: 500});
}, {concurrency: 500}).then((reponse) => {
console.log("data inserted");
})
}).catch((error) => {
console.log(error);
});
}
现在在名为 syncCustomerWithCustomerv1 的函数中,我可以将旧集合中的数据提取到新集合中,但我认为不会有任何并发请求。在上述操作运行时,我无法点击 api,所以当操作运行时,它不允许其他请求一起运行。
在 Promise.map(aggregateDocumentsv1) 中,我正在获取游标列表。 listOfCursor 数组中的每个元素都有一个游标,查询时会产生 500 条记录。
我希望它获取每个光标并将其分配给下一个 Promise.map(getCustomerDatav1(cursor)),现在这会产生我以前的 mongo 集合中的每个客户,我们可以在我们得到的对象,然后将数据插入到新的集合中。
如果有人遇到问题并知道如何使其更好地并发,以便我可以运行此脚本并且我的 API 也不会出现任何停机时间。
【问题讨论】:
-
你到底想达到什么目的?? bluebird 中的并发性对并发执行的操作设置了限制,即在任何时间段内最多有 500 个解析器函数实例正在运行。如果您不指定此选项,则该函数将同时在您的所有文档上调用。
-
我认为你有这个错误的方式。
Promise.map(arrayOfItems, e => functionReturningPromise(e))基本上是Promise.all(arrayOfItems.map(e => functionReturningPromise(e))的“帮手”。您同时提供了“承诺数组”并尝试“迭代”结果,但这不是Promise.map()的函数参数所做的。 -
嘿@ilLunn NeilLunn,所以应该有第二个 Promise.map 需要重写为 Promise.any。
-
如果你看一下我的用法示例,first 参数基本上是一个数组,second 是基本上是
Array.prototype.map()的函数。最重要的是,这意味着返回一个数据数组,而您忽略了该返回。建议您宁愿解释您正在尝试做的事情,因为代码有点混乱,并且您实际上是在包装已经返回 Promise 和新 Promise 的方法。尝试了解问题中的点应该发生的事情的逻辑。 -
嗯。我可以在这里尝试一个简化的解释吗?看来您实际上是 1. 从一个集合中读取客户名称和电子邮件。 2. 执行“查找或创建”以将相同的名称和电子邮件数据写入另一个集合。问题是“这是在同一个数据库服务器上,还是在不同的机器上?目标集合(“查找或创建”一个)实际上是否已经预先存在其中的数据,或者它可以完全被覆盖”。这是我的基本解释,实际上是我想让你解释的。没有冒犯,但试图解释当前的代码没什么意义。
标签: node.js mongodb promise bluebird