在$ project阶段的聚合中获取子文档字段

时间:2017-02-13 01:14:55

标签: node.js mongodb mongoose

我正在使用以下架构:

问题架构:

filter_size - 1

回答架构:

var Question = new Schema({
      title: String,
      content: String,
      createdBy: {
          type: Schema.ObjectId,
          ref: 'User',
          required: true
        },
      answers: {
         type: [ { type: Schema.Types.ObjectId, ref: 'Answer' } ]
       }
    });

我正在尝试进行汇总,我可以将所有问题的列表与var Answer = new Schema({ content:String, createdBy: { type: Schema.Types.ObjectId, ref: 'User', }, isBest: { type: Boolean, default: false }, createdAt: Date, votes: Number }); title 等相关联的字段列出来(这些字段将在聚合)createdByanswers_count字段,如果has_best已经有最佳答案,则该字段为真(该字段的答案为最佳等于真实的)

我尝试使用question管道:

$project

此外,我尝试 Question.aggregate([{ $project: { answers_count: { $size: '$answers' }, title: true, createdAt: true, createdBy: true, has_best_answer: '$answers.isBest' } }, { $sort: { createdAt: -1 } }], function(err, questions){ if(err){ return res.status(400).send({ message: err }); } User.populate(questions, { path: 'createdBy', model: 'User', select: 'firstname lastname image' }, function(err, questions){ return res.json(questions); }); }); 数组,然后$unwind获取答案,但在执行$lookup时没有结果。这是我尝试使用answers_count$unwind的内容。

$lookup

因此,因为数组中的Question.aggregate([ { $unwind: '$answers' }, { $lookup: { from: 'answers', localField: 'answers', foreignField: '_id', as: 'answer' } },{ $project: { title: true, createdBy: true, createdAt: true, has_best_answer: '$answer.isBest' } } ], function(err, questions){ if(err){ return res.status(400).send({ message: err }); } User.populate(questions, { path: 'createdBy', model: 'User', select: 'firstname lastname image' }, function(err, questions){ return res.json(questions); }); }); 不能在answer数组$unwind中执行$size字段,所以当我尝试answers_count使用uniques {时{1}}像这样:

$group

我有这个结果:

questions id

这是我正在寻找的输出:

Question.aggregate([
  {
    $unwind: '$answers'
  },
  {
    $lookup: {
      from: 'answers',
      localField: 'answers',
      foreignField: '_id',
      as: 'answer'
    }
  },{
    $project: {
      title: true,
      createdBy: true,
      createdAt: true,
      has_best_answer: '$answer.isBest'
    }
  },
  {
    $group: { _id: '$_id' }
  }
], function(err, questions){
  if(err){
    return res.status(400).send({ message: err });
  }
  User.populate(questions, { path: 'createdBy', model: 'User', select: 'firstname lastname image' }, function(err, questions){
    return res.json(questions);
  });
});

1 个答案:

答案 0 :(得分:0)

您可以尝试以下内容。

$lookup - 此阶段将所有answers加入问题文档。

$project - 此阶段投影所有必填字段。 answers_count - 计算answers数组中项目总数。 has_best_answer - 迭代answers并比较任何isBest字段值是否为真。

Question.aggregate([
  {
    $lookup: {
      from: 'answers',
      localField: 'answers',
      foreignField: '_id',
      as: 'answers'
    }
  },{
    $project: {
      title: true,
      createdBy: true,
      createdAt: true,
      answers_count: { $size: '$answers' },
      has_best_answer: 
        { $anyElementTrue: {
            $map: {
                input: "$answers",
                as: "answer",
                in: { $eq: [ "$$answer.isBest", true] }
            }
        }}
    }
  }
]);