TypeError:populate(...)。exec不是函数

时间:2016-11-15 14:07:44

标签: javascript mongodb mongoose schema mongoose-populate

我基本上相信这个错误是由于我调用的对象不包含.populate函数,尽管我不知道如何将其更改为有效。

首先,这是完整的错误。

TypeError: exam[0].modules[u].topics[i].populate(...).exec is not a function
    at /home/ubuntu/workspace/tests/app.js:425:84
    at Query.Model.$wrapCallback (/home/ubuntu/workspace/tests/node_modules/mongoose/lib/model.js:3336:16)
    at /home/ubuntu/workspace/tests/node_modules/mongoose/node_modules/kareem/index.js:259:21
    at /home/ubuntu/workspace/tests/node_modules/mongoose/node_modules/kareem/index.js:127:16
    at nextTickCallbackWith0Args (node.js:420:9)
    at process._tickCallback (node.js:349:13)


Process exited with code: 1

我所指的具体行是exam[0].modules[u].topics[i].populate("questions").exec(function(err,quests)另一行我认为非常重要的是行examBoard.find({name:req.body.examBoardName},function(err,exam),它返回exam,但不包含.populate功能。

我认为这很大程度上取决于我缺乏经验,而不是逻辑错误,但我不确定。

以下是包含错误的代码部分。

app.post("/test",function(req,res)
{
    console.log("\n\n\n\n")
    var time = req.body.time;
    var topicName = [req.body.topic1,req.body.topic2,req.body.topic3,req.body.topic4,req.body.topic5];
    var topicsArray = [];
    examBoard.find({name:req.body.examBoardName},function(err,exam)
    {
        if(err)
        {
            console.log(err);
        }
        else
        {
            for(var u=0;u<exam[0].modules.length;u++)
            {
                console.log("exam[0].modules[u]:\n"+exam[0].modules[u]);
                console.log("req.body.moduleName:\n"+req.body.moduleName);
                if(exam[0].modules[u].name==req.body.moduleName)
                {
                    console.log("topicName[]:\n"+topicName[0]+"\n"+topicName[1]+"\n"+topicName[2]+"\n"+topicName[3]+"\n"+topicName[4]);
                    for(var i=0;i<exam[0].modules[u].topics.length;i++)
                    {
                        console.log("exam[0].modules[u].topics[i].name:\n"+exam[0].modules[u].topics[i].name);
                        for(var t=0;t<topicName.length;t++)
                        {
                            if(exam[0].modules[u].topics[i].name==topicName[t])
                            {
                                // exam[0].modules[u].topics[i].find({name:topicName[t]}).populate("questions").exec(function(err,quests)
                                exam[0].modules[u].topics[i].populate("questions").exec(function(err,quests)
                                {
                                    if(err)
                                    {
                                        console.log(err);
                                    }
                                    else
                                    {
                                        console.log("exam[0].modules[u].topics[i].questions:\n"+exam[0].modules[u].topics[i].questions);
                                        topicsArray.push({
                                            name:topicName[i],
                                            questions:quests
                                        });
                                    }
                                });    
                            } 
                        }
                    }
                    break;
                }
            }
        }
    });
});

以下是examBoard架构。

var mongoose = require("mongoose");

var topicSchema = new mongoose.Schema({
    name: String,
    questions:[
        {
            type:mongoose.Schema.Types.ObjectId,
            ref:"question"
        }
    ],
});

var moduleSchema = new mongoose.Schema({
    name: String,
    topics: [topicSchema]
});

var examBoardSchema = new mongoose.Schema({
    name: String,
    modules: [moduleSchema]
});

module.exports = mongoose.model("examBoard", examBoardSchema);

这里只是为了防止这里出现问题,是导入模式。

var express                 = require("express"),
    mongoose                = require("mongoose"),
    passport                = require("passport"),
    bodyParser              = require("body-parser"),
    LocalStrategy           = require("passport-local"),
    passportLocalMongoose   = require("passport-local-mongoose"),

    seedDB                  = require("./seeds"),
    question                = require("./models/question"),
    examBoard               = require("./models/examBoard"),
    user                    = require("./models/user");

1 个答案:

答案 0 :(得分:0)

您正在从populate调用exam[0].modules[u].topics[i]方法,但实际上持有此方法的模型对象为exam[0],因此您可以在深层对象层次结构中填充问题,如下所示:

exam[0].populate("modules.topics.questions")

但是,等一下,现在该模型将填充此考试所有模块所有主题中的问题。

在您的情况下,您首先按 moduleName 进行过滤,这样您就可以配置populate选项,所以就像这样:

var options = {
    path: 'modules.topics.questions',
    match: { 'modules.name': req.body.moduleName }
};

exam[0].populate(options)

了解docspopulate参数的更多信息。