使用Node.js monk和MongoDB链接嵌套的异步查找

时间:2015-07-14 07:31:42

标签: node.js mongodb monk

使用Node.js monk和MongoDB,我想模仿表连接:

  1. 查找集合A
  2. 对于每个结果X,在集合B中执行查找,并更新X
  3. 返回更新的结果列表
  4. monk中数据库命令的异步性质给我带来了麻烦。 这是我的初始代码。它不起作用,因为第二次调用find会立即返回一个承诺, xs中的结果将在响应中发送,然后才能更新。

    var db = require('monk')('localhost/mydb');
    db.get('collection').find({}, function(e,xs) {
      xs.forEach(function(x){
        coll_b.find({a_id:x._id}, function(e,bs) {
          a['bs'] = bs;
        });
      });
      res.json({'results':as});
    });
    

    我觉得我应该在这里使用承诺链,但我无法弄清楚如何做到这一点。 任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

我想我以这种方式解决了它,受到this answer的启发:

<%# app/views/students/index.html.erb %>
<h1>Students</h1>

    <%= form_for_filterrific @filterrific do |f| %>
  <div>
    Search
    <%# give the search field the 'filterrific-periodically-observed' class for live updates %>
    <%= f.text_field(
      :search_query,
      class: 'filterrific-periodically-observed'
    ) %>
  </div>
  <div>
    Country
    <%= f.select(
      :with_country_id,
      @filterrific.select_options[:with_country_id],
      { include_blank: '- Any -' }
    ) %>
  </div>
  <div>
    Registered after
    <%= f.text_field(:with_created_at_gte, class: 'js-datepicker') %>
  </div>
  <div>
    Sorted by
    <%= f.select(:sorted_by, @filterrific.select_options[:sorted_by]) %>
  </div>
  <div>
    <%= link_to(
      'Reset filters',
      reset_filterrific_url,
    ) %>
  </div>
  <%# add an automated spinner to your form when the list is refreshed %>
  <%= render_filterrific_spinner %>
<% end %>

<%= render(
  partial: 'students/list',
  locals: { students: @students }
) %>

我仍然觉得使用var db = require('monk')('localhost/mydb'); // Initial find db.get('collection').find({}, function(e,xs) { // Get inner finds as a list of functions which return promises var tasks = xs.map(function(x){ return function() { return coll_b.find({a_id:x._id}, function(e,bs) { a['bs'] = bs; }); } }); // Chain tasks together var p = tasks[0](); // start the first one for(var i = 1; i < tasks.length; i++) p = p.then(tasks[i]); // After all tasks are done, output results p.then(function(_x){ res.json({'results':xs}); }); }); 可以最小化此代码,但至少这可以按预期工作。

注意:我意识到为每个结果执行第二次查找并不一定有效,但这不是我关注的问题。