Mongoose的populate方法打破了承诺链?

时间:2014-11-03 01:40:32

标签: express mongoose mongoose-populate

所以我有一个像这样的mongoose Schema:

var Functionary = new Schema({
  person: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Person'
  },
  dateOfAssignment: Date,
  dateOfDischarge: Date,
  isActive: Boolean
});

var PositionSchema = new Schema({
  name: String,
  description: String,
  maxHeadCount: Number,
  minHeadCount: Number,
  currentHeadCount: Number,
  currentlyHolding: [Functionary],
  historical: [Functionary],
  responsibleTo: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Position'
  }
});

*请注意,位置文档可以在ResponsibleTo字段中引用自身。

现在,我正在尝试构建一个方法来搜索Positions集合,填充currentlyHolding[].person.name fieldresponsibleTo.currentlyHolding[].person.name字段,并返回找到的记录总数(用于前端的寻呼目的。)

以下是我的代码:

exports.search = function(req, res) {
  var result = {
    records: null,
    count: 0,
    currentPage: req.params.page,
    totalPages: 0,
    pageSize: 10,
    execTime: 0
  };

  var startTime = new Date();

  var populateQuery = [
    {
      path: 'currentlyHolding.person',
      select: 'name'
    }, {
      path:'responsibleTo',
      select:'name currentlyHolding.person'
    }
  ];

  Position.find(
    {
      $or: [
        { name: { $regex: '.*' + req.params.keyword + '.*', $options: 'i' } },
        { description: { $regex: '.*' + req.params.keyword + '.*', $options: 'i' } }
      ]
    },
    {},
    {
      skip: (result.currentPage - 1) * result.pageSize,
      limit: result.pageSize,
      sort: 'name'
    })
  .exec()
  .populate(populateQuery)
  .then(function(doc) {
    result.records = doc;
  });

  Position.count(
    {
      $or: [
        { name: { $regex: '.*' + req.params.keyword + '.*', $options: 'i' } },
        { description: { $regex: '.*' + req.params.keyword + '.*', $options: 'i' } }
      ]
    })
  .exec()
  .then(function(doc) {
    result.count = doc;
    result.totalPages = Math.ceil(result.count / result.pageSize);
  })
  .then(function() {
    var endTime = new Date();
    result.execTime = endTime - startTime;
    return res.json(200, result);
  });
};

我的问题是当我使用populate方法运行第一个查询时(如图所示),它不起作用。我带走了填充物并且它有效。填充方法是否会破坏承诺?如果是这样,有没有更好的方法来实现我想要的目标?

1 个答案:

答案 0 :(得分:1)

你提问已经有一段时间了,但这可能仍然有助于其他人,所以我们去了:

According to the docs.populate()不会返回承诺。要实现这一目标,您应该链接.execPopulate()

或者,您可以将.populate()放在.exec()之前。后者将终止查询构建器界面并为您返回一个承诺。