簡體   English   中英

在 $project 聚合階段獲取一個子文檔字段

[英]get a sub document field in $project stage of aggregation

我正在使用以下模式:

問題架構:

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    
});

我正在嘗試進行聚合,結果我可以得到所有問題的列表,其中包含特定字段,如titlecreatedBy (將在聚合后填充)answers_counthas_best字段,這將是如果question已經有最佳答案(字段 isBest 的答案等於 true),則為 true

我嘗試使用$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);
  });
});

因此,因為數組中的$unwind不能在 answers 數組中使用$size來執行answers_count字段,所以當我嘗試使用$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);
  });
});

我有這個結果:

[
   {
      "_id": "5825f2846c7ab9ec004f14ce"
   },
   {
      "_id": "5823b9309de40494239c95cd"
   },
   {
      "_id": "582538366062607c0f4bcdaa"
   },
   {
      "_id": "5855d319b6a475100c7beba2"
   },
   {
    "_id": "5878156328dba3d02052b321"
   }
 ]

這是我正在尋找的輸出:

[
   {
      _id: '5825f2846c7ab9ec004f14ce',
      title: 'Some question title',
      createdBy: '5855d319b6a475100c7beba2', // this is going to be       populated,
      createdAt: '2016-11-10T00:02:56.702Z',
      answers_count: 5,
      has_best_answer: true
   },
  {
     _id: '5825f2846c7ab9ec004f14ce',
     title: 'Some other question title',
     createdBy: '5855d319b6a475100c7beba2', // this is going to be populated,
     createdAt: '2016-11-10T00:02:56.702Z',
     answers_count: 2,
     has_best_answer: false
  }
]

你可以試試下面的方法。

$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] }
            }
        }}
    }
  }
]);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM