Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 在聚合的$project阶段获取子文档字段_Node.js_Mongodb_Mongoose_Aggregation Framework - Fatal编程技术网

Node.js 在聚合的$project阶段获取子文档字段

Node.js 在聚合的$project阶段获取子文档字段,node.js,mongodb,mongoose,aggregation-framework,Node.js,Mongodb,Mongoose,Aggregation Framework,我正在使用以下模式: 问题模式: var Question = new Schema({ title: String, content: String, createdBy: { type: Schema.ObjectId, ref: 'User', required: true }, answers: { type: [ { type: Schema.T

我正在使用以下模式:

问题模式:

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    
});
答案模式:

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
createdBy
(将在聚合后填充),
回答\u计数
有\u最佳
字段,如果
问题
已经有了最佳答案,则该字段将为真(带该字段的答案最好等于真)

我尝试了
$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);
  });
});
此外,我还尝试
$展开
数组,然后
$查找
以查找答案,但在执行
答案\u计数时没有结果。这就是我用
$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
,无法
$size
在answers数组中执行
answers\u count
字段,也就是当我尝试执行
$group
以获得唯一的
问题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
-此阶段将所有
答案连接到问题文档

$project
-此阶段将投影所有必需字段<代码>答案\u计数
-统计
答案
数组中的项目总数<代码>具有最佳答案
-迭代一个
答案
,并比较
是最佳答案
字段值是否为真

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

您能在使用
$unwind
/
$lookup
的地方添加代码吗?添加一些您正在测试查询的示例文档。我刚刚编辑了问题:)它工作得很好,但是
有\u best\u答案
总是
false
我刚刚在:{$eq:[“$$answer.isBest”,true]}中做了一个更改
。你有最新的更新吗?是的,我有,因为某些原因总是错误的。你有属性
isBest
as
boolean
string
?是布尔的,
isBest:{type:boolean,default:false}