javascript - 如何强制 Mongoose Save() 调用同步

标签 javascript mongodb mongoose

我正在用 Node.js 编写一个脚本,它需要执行以下操作:

  1. 打开 XML 文件
  2. 对于文件中的每个节点
  3. 执行 mongodb 查找以尝试查找与此节点相关的对象
  4. 如果找不到对象,则创建它,否则以某种方式操作找到的对象
  5. 将(可能是新的)对象保存回数据库。
  6. 转到第 2 步

我已经研究了一段时间,得出的结论是,使用异步 mongodb 几乎不可能做到这一点。问题是多方面的,但是例如,如果您要处理 20,000 个这样的节点,那么异步执行会挂起脚本。但是,由于第 4 步需要查看对象是否已经存在,因此将它们作为批量插入进行是不可行的。

可以将一些可怕的东西拼凑在一起,缓存创建的对象,然后将它们保存为类似于步骤 7 的内容,但这会很困难,因为对象要进入多个集合,您需要尝试在第 4 步首先从缓存中查找对象,然后从数据库中查找。如果这是解决方案,那么我将把 Javascript 注销为损坏,然后用 perl 编写它。所以我的问题是,对于像上述 Action 序列这样简单的事情,我可以以某种方式强制 mongodb同步,这样我的脚本就不会变得疯狂吗?我希望能够说 document.save() (顺便说一下,我正在使用 Mongoose),然后让它在实际保存后才返回。

编辑:添加代码

这从循环中调用了大约 20000 次。我不在乎(在合理范围内)需要多长时间,但是 200,000 次异步调用保存会挂起脚本,所以它不可能是这样(那时它还使用了超过 1.5gig 的 ram)。如果我不能让 hObj.save(); 等到对象被实际保存,那么我将需要用更强大的语言编写它。

    models('hs').findOne({name: r2.$.name}, function (err, h) {
    if (err) {
        console.log(err);
    } else {
        var resultObj = createResult(meeting, r1, r2);

        if (h == undefined) {

            var hObj = new models('hs')({
                name : r2.$.name,
                results : [resultObj],
                numResults : 1
            });

            hObj.save();
        } else {
            h.results.push(resultObj);
            h.numResults++;
            h.save();
        }
    }
});

最佳答案

来自 async github页面:

eachSeries(arr, iterator, callback)

The same as each, only iterator is applied to each item in arr in series. The next iterator is only called once the current one has completed. This means the iterator functions will complete in order.

所以假设你在 nodes

中有你的 XML 节点
async.eachSeries(
  nodes,
  // This will be applied to every node in nodes
  function (node, callback) {
    models('hs').findOne({name: r2.$.name}, function (err, h) {
      if (err) {
        console.log(err);
      } else {
        // Async?
        var resultObj = createResult(meeting, r1, r2);

        if (h == undefined) {

          var hObj = new models('hs')({
            name : r2.$.name,
            results : [resultObj],
            numResults : 1
          });

          hObj.save(function (err, p) {
            // Callback will tell async that you are done
            callback();
          });
        } else {
          h.results.push(resultObj);
          h.numResults++;
          h.save(function (err, p) {
            // Callback will tell async that you are done
            callback();
          });
        }
      }
    });
  },
  // This will be executed when all nodes has been processed
  function (err) {
    console.log('done!');
  }
);

关于javascript - 如何强制 Mongoose Save() 调用同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23968977/

相关文章:

javascript - 我需要加载 JQuery 才能完成这项工作吗?

mongodb - pymongo中如何指定分片键字段的顺序? (对于 mongodb)

node.js - 带有自己的 ObjectId 的 Mongoose 自引用抛出 : cast to ObjectId failed

node.js - 为什么使用 Mongoose 模型而不仅仅是架构/文档?

javascript - 在 {{/if}} 中打开一个 div 并稍后使用 Meteor/blaze 关闭它

javascript - 将特定字符串解析为对象

jquery - 如何有条件地为 Jade 中的文本分配颜色

node.js - if else if cond in mongodb 聚合

javascript - 从 API 获取数据并使用 javascript 解析它

node.js - nodejs-native-mongodb 的 runCommand 等效项