2016-06-11 80 views
7

这些是我的模式(主题是家长和包含的“思想的列表):在猫鼬填充嵌套数组 - Node.js的

var TopicSchema = new mongoose.Schema({ 
    title: { type: String, unique: true }, 
    category: String, 
    thoughts: [ThoughtSchema] 
}, { 
    timestamps: true, 
    toObject: {virtuals: true}, 
    toJSON: {virtuals: true} 
}); 

var ThoughtSchema = new mongoose.Schema({ 
    text: String, 
    author: {type: mongoose.Schema.Types.ObjectId, ref: 'User'}, 
    votes:[{ 
    _id:false, 
    voter: {type: mongoose.Schema.Types.ObjectId, ref: 'User'}, 
    up: Boolean, 
    date: {type: Date, default: Date.now} 
    }] 
}, { 
    timestamps: true, 
    toObject: {virtuals: true}, 
    toJSON: {virtuals: true} 
}); 

.... 

我想读思想的作家和改变我的获取主题API像这样:

... 
    var cursor = Topic.find(query).populate({ 
    path: 'thoughts', 
    populate: { 
     path: 'author', 
     model: 'User' 
    } 
    }).sort({popularity : -1, date: -1}); 

    return cursor.exec() 
    .then(respondWithResult(res)) 
    .catch(handleError(res)); 
... 

但作者是空的。我也没有在控制台中得到任何错误。这里有什么问题?

编辑:其实我不需要思想作为模式,它没有自己的数据库集合。它将被保存在主题中。但为了使用时间戳选项,我需要将其内容提取到新的本地模式ThoughtSchema。但是我现在直接在主题的想法数组中定义了thinkSchema的内容,但它仍然无效。

Edit2:这是执行前的游标对象。不幸的是,我不能在Webstorm调试,这是从节点督察截图:使用Model.populate

enter image description here

+0

@Theodore答案对我来说看起来是正确的:查询的内容是什么?你有选择吗? – pasine

+0

我已经上传了游标对象内容的截图,在它执行之前 – akcasoy

回答

0

如何

Topic.find(query).populate('thoughts') 
.sort({popularity : -1, date: -1}) 
.exec(function(err, docs) { 
    // Multiple population per level 
    if(err) return callback(err); 
    Topic.populate(docs, { 
    path: 'thoughts.author', 
    model: 'User' 
    }, 
    function(err, populatedDocs) { 
    if(err) return callback(err); 
    console.log(populatedDocs); 
    }); 
}); 
+0

nope :(....... – akcasoy

0

你试试?

Topic.find(query).populate('thoughts') 
.sort({popularity : -1, date: -1}) 
.exec(function(err, docs) { 
    // Multiple population per level 
    if(err) return callback(err); 
    Thought.populate(docs, { 
    path: 'thoughts.author', 
    model: 'User' 
    }, 
    function(err, populatedDocs) { 
    if(err) return callback(err); 
    console.log(populatedDocs); 
    }); 
}); 

UPDATE:
你可以deep populate这样的尝试:

Topic.find(query).populate({ 
    path: 'thoughts', 
    populate: { 
    path: 'author', 
    model: 'User' 
    } 
}) 
.sort({popularity : -1, date: -1}) 
.exec(function(err, docs) { 
    if(err) return callback(err); 
    console.log(docs); 
}); 
+0

'Thought'没有被导出。我也不知道如何导出多个模式......这是唯一的出口行:出口默认mongoose.model('主题',TopicSchema); – akcasoy

+0

你不需要导出它,因为你正在使用它作为嵌入式模式。在这种情况下,我确认@ Theodore的答案应该工作。检查你的数据库?是否正确保存'作者'的引用? – pasine

+0

是的..作者字段有用户的ID。但我不知道怎么调试webstorm的服务器端代码,看看如何查询..我会尝试在接下来的几天中进行调试 但是关于“思想”模式..当我使用Thought.populate的时候,如你所建议的那样,应用程序不能被编译......像“Thought is undefined”那样出现在终端 – akcasoy

0

这些都是模式:

var TopicSchema = new mongoose.Schema({ 
    title: { type: String, unique: true }, 
    category: String, 
    thoughts: [ThoughtSchema] 
}, { 
    timestamps: true, 
    toObject: {virtuals: true}, 
    toJSON: {virtuals: true} 
}); 

var ThoughtSchema = new mongoose.Schema({ 
    text: String, 
    author: {type: mongoose.Schema.Types.ObjectId, ref: 'User'}, 
    votes:[{ 
    _id:false, 
    voter: {type: mongoose.Schema.Types.ObjectId, ref: 'User'}, 
    up: Boolean, 
    date: {type: Date, default: Date.now} 
    }] 
}, { 
    timestamps: true, 
    toObject: {virtuals: true}, 
    toJSON: {virtuals: true} 
}); 

你尝试聚集而是填充的。聚合使用$lookup可以更容易地填充嵌入的数据。尝试下面的代码。

UPDATE

Topic.aggregate([{$unwind: "$thoughts"},{ $lookup: {from: 'users', localField: 'thoughts.author', foreignField: '_id', as: 'thoughts.author'}},{$sort:{{popularity : -1, date: -1}}}],function(err,topics){ 
console.log(topics) // `topics` is a cursor. 
// Perform Other operations here. 
}) 

说明

$放松:解构阵列场从输入文档输出为每个元素的文档。

$查找:$ lookup阶段在输入文档的字段与“已加入”集合的文档中的字段之间执行相等匹配。查找人口的工作。

$查找就像

:这个说从中收集数据需要被填充(users在这种情况下)。

localField:这是需要填充的本地字段。 (在这种情况下为thoughts.author)。

foreignField:这是本从中数据需要被填充(_id字段中users收集在该场景)的集合中的外来场。

as:这是您想要显示连接值的字段。 (这将把ideas.author的id作为thoughts.author文档)。

希望这个工程。

+0

“你有没有尝试聚合而不是填充”对不起..但聚合通常用于“匹配”,而不是“发现”据我所知..所以它不是一种替代方案填充,但'找到'我认为..所以我不知道如何将此集成到我的代码..聚合返回也是一个游标对象,必须执行后?你能否在问题中更新我的第二个代码并写出所有的行? – akcasoy