我正在使用以下mongoose schemas
:
问题架构:
var Question = new Schema({
title: String,
content: String,
createdBy: {
type: Schema.ObjectId,
ref: 'User',
required: true
},
answers: {
type: [ { type: Schema.Types.ObjectId, ref: 'Answer' } ]
}
});
回答Shchema:
var Answer = new Schema({
content: {
type: String,
require: 'Content cannot be empty.'
},
createdBy: {
type: Schema.Types.ObjectId,
ref: 'User'
},
isBest: {
type: Boolean,
default: false
},
createdAt: {
type: Date,
default: Date.now
},
votes: {
type: Number,
default: 0
},
comments: {
type: [{ type: Schema.Types.ObjectId, ref: 'Comment' }]
}
});
和评论架构:
var Comment = new Schema({
content: {
type: String,
required: [true, 'Content cannot be empty']
},
createdBy: {
type: Schema.Types.ObjectId,
ref: 'User'
},
createdAt: {
type: Date,
default: Date.now
}
});
基本上我要做的是在每个$lookup
中为answers
和comments
数组执行answer
,然后在$project
阶段如果用户登录的是isOwner
或true
的所有者,请尝试添加answer
字段comment
。这就是我的尝试:
Question.aggregate([
{
$match: { '_id': { $eq: questionId } }
},
{
$lookup: {
from: 'answers',
localField: 'answers',
foreignField: '_id',
as: 'answers'
}
},{
$lookup:{
from: 'comments',
localField: 'answers.comments',
foreignField: '_id',
as: 'comments'
}
}, {
$project: {
title: true,
content: true,
createdBy: true,
createdAt: true,
isOwner: { $eq : ['$createdBy', currentUser] },
answers: true,
answers: {
isOwner: { $eq : ['$createdBy', currentUser] },
content: true,
createdBy: true,
createdAt: true,
comments: {
content: true,
createdAt: true,
createdBy: true,
isOwner: { $eq : ['$createdBy', currentUser] }
}
}
}
}
])
这是我期待的输出:
{
"_id": "58a7be2c98a28f18acaa4be4",
"title": "Some title",
"createdAt:": "2017-03-03T05:13:41.061Z",
"content": "some content",
"isOwner": true,
"createdBy": {
"_id": "58a3a66c088fe517b42775c9",
"name": "User name",
"image": "imgUrl"
},
"answers": [
{
"_id": "58a3a66c088fe517b42775c9",
"content": "an answer content",
"createdAt": "2017-03-03T05:13:41.061Z",
"isBest": false,
"isOwner": false,
"createdBy":{
"_id": "58a3a66c088fe517b42775c9",
"name": "another user",
"image": "another image"
},
"comments": [
{
"_id": "58aa104a4254221580832a8f",
"content": "some comment content",
"createdBy": {
"_id": "58a3a66c088fe517b42775c9",
"name": "another user",
"image": "another image"
},
}
]
}
]
}
我正在使用mongodb 3.4.2
答案 0 :(得分:1)
您的代码存在的问题是您在查找之前没有展开answeeres数组 请查看以下评论
Question.aggregate([
{
$match: { '_id': { $eq: questionId } }
},
{
$lookup: {
from: 'answers',
localField: 'answers',
foreignField: '_id',
as: 'answers'
}
},
{$unwind : "$answers"}, // <-- Check here
{
$lookup:{
from: 'comments',
localField: 'answers.comments',
foreignField: '_id',
as: 'comments'
}
},
{
$group : {
_id : null,
title: {$first : true},
content: {$first :true},
createdBy: {$first :true},
createdAt: {$first :true},
isOwner: { $eq : ['$createdBy', currentUser] },
answersStatus: {$first :true},
answers : {$push : $answer}
}
}
])
答案 1 :(得分:1)
您可以尝试addFields
阶段为所有关系添加isOwner
字段。
Question.aggregate([{
$match: {
'_id': {
$eq: questionId
}
}
}, {
$addFields: {
"isOwner": {
$eq: ['$createdBy', currentUser]
}
}
}, { // No unwind needed as answers is scalar of array values.
$lookup: {
from: 'answers',
localField: 'answers',
foreignField: '_id',
as: 'answers'
}
}, {
$addFields: {
"answers.isOwner": {
$eq: ['$createdBy', currentUser]
}
}
}, {
$unwind: "$answers" //Need unwind here as comments is array of scalar array values
}, {
$lookup: {
from: 'comments',
localField: 'answers.comments',
foreignField: '_id',
as: 'comments'
}
}, {
$addFields: {
"comments.isOwner": {
$eq: ['$createdBy', currentUser]
}
}
}, {
$addFields: { // Move the comments back to answers document
"answers.comments": "$comments"
}
}, {
$project: { // Remove the comments embedded array.
"comments": 0
}
}, {
$group: {
_id: null,
isOwner: {
$first: "$isOwner"
},
answers: {
$push: "$answers"
}
}
}])