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
asboolean
或string
?是布尔的,isBest:{type:boolean,default:false}