node.js - 优化异步查询 Node

标签 node.js mongodb optimization async-await

我正在一个有超过25,000个用户的项目中,每次为Oppurtinity module创建任何记录时,它都会执行此功能,该功能会在mongodb中为每个用户插入通知详细信息,
问题在于它占用了cpu,并且不让任何其他API产生结果,直到此异步结束为止,这会占用时间,同时服务器不会加载任何其他数据/它会给出较晚的响应。

  • Node -v10.15.3
  • MongoDB shell版本v4.0.17
  • Server = Windows = Memory-8GB
  • CPU 2.70GHz speed

  • 我想知道,这里的问题是什么,代码是什么,如果可以的话,我该如何优化它?
    async.eachSeries(users, (eachuser, next) => {
         db.notifications.find({user_id:eachuser._id},function(errr,opp_noti){
            if(opp_noti.length != 0){
              db.notifications.update( { user_id:eachuser._id},{$push:{oppurtunity:oppurtunity_id}},function(errr,result){
                })
            }else{
            db.notifications.insert({user_id:eachuser._id,oppurtunity:[oppurtunity_id]},function(errr,result){
             })
            }
           })
        next();
    })
    

    最佳答案

    您的示例代码和您的问题有一些问题。我必须假设您正在使用以下库:AsyncMongoDB。请尝试更好地整理您的问题。
    如果我假设正确,则由于未正确实现async.eachSeries函数,因此您没有仔细阅读文档-eachSeries期望async函数作为第二个参数。
    我已经基于这两个库的文档重写了您的代码。我以前从未使用过它们,但我有把握地确信它是正确的。

    async.eachSeries(users, async (user) => {
        const user_id = user._id;
        const cursor = db.notifications.find({ user_id });
        const count = await cursor.count();
        if (count > 0) {
            return db.notifications.update({ user_id },
                {
                    $push: { oppurtunity: oppurtunity_id } // where is oppurtunity_id defined?
                }
            )
        } else {
            return db.notifications.insert({
                user_id,
                oppurtunity: [oppurtunity_id]
            })
        }
    })
    
    您可能已经意识到这一点,但是async.eachSeries将通过依次运行它们来限制请求。尽管出于各种原因这可能是必需的,但它会减慢该过程,并且不会利用Node的非阻塞性质。 async.each将并行运行它们,这在理论上是最快的,但是在25K记录下可能会引起问题。因此,我建议您采取中间立场,并考虑使用async.eachOfLimit,设置并行限制并查看其性能。
    您也可以通过不查询每个用户的数据库来进一步解决该问题并获得显着的性能提升。尝试在一个查询中让所有需要提前更新的用户。
    类似于以下内容的内容将在一个查询中返回notifications集合中的所有ID(可能在底层查询中返回多个ID,但仍比n好得多)。
    const user_ids = db.notifications.find({}, { _id:1 }).map(item => item._id)
    
    一旦有了ID,就可以创建两个工作负载,一个工作负载来运行所有db.notifications.update查询,另一个工作负载来运行所有db.notifications.insert查询。

    关于node.js - 优化异步查询 Node ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65231833/

    相关文章:

    node.js - kafka nodejs - 使用 SASL 身份验证创建生产者和消费者时出现的问题

    mysql - 优化嵌套查询

    python - 使用 Python 优化列表操作代码

    javascript - 如何在您的 Ionic/AngularJs 应用程序中包含和使用 Node 模块?

    javascript - 有没有办法检查JS中的字符串是否是单个表情符号?

    Javascript 正则表达式替换捕获

    python - 使用 pymongo 和 Flask 对 MongoDB 结果中的项目进行聚合和计数

    javascript - 灵活的 JavaScript 函数(适用于 MongoDB)

    mongodb - 如何在AppFog/CloudFoundry上使用MongoDB部署Grails?

    C中使用链表的CPU缓存缺点