【问题标题】:mongoose.js: _id of embedded documentmongoose.js:嵌入文档的_id
【发布时间】:2013-08-07 22:10:16
【问题描述】:

我正在尝试使用 mongoose 和 MongoDB 将任务保存到任务列表中。我想将它冗余地保存在任务集合和相应的列表文档中作为嵌入文档。

它工作正常,但有一点:列表的嵌入文档没有它们的 objectId。但我需要它们以便将它们与任务集合中的文档进行逻辑连接。

我的架构:

var TaskSchema = new Schema({
    _id: ObjectId,
    title: String,
    list: ObjectId

});

var Task = mongoose.model('task', TaskSchema);

var ListSchema = new Schema({
    _id: ObjectId,
    title: String,
    tasks: [Task.schema]
});

var List = mongoose.model('list', ListSchema);

我的控制器/路由器:

app.post('/lists/:list_id/tasks', function(req, res) {

        var listId = req.params.list_id;   

        // 1. Save the new task into the tasks-collection.

        var newTask = new Task();
        newTask.title = req.body.title;
        newTask.list = listId; 

        console.log('TaskId:' + newTask._id);  // Returns undefined on the console!!!

        newTask.save(); // Works fine!

        // 2. Add the new task to the coresponding list.

        list.findById(listId, function(err, doc){

            doc.tasks.push(newTask);

            doc.save();  // Saves the new task in the list but WITHOUT its objectId

            });

        res.redirect('/lists/' + listId)

});

我可以使用猫鼬不同的方式来实现吗?还是我必须先保存任务,然后在将其保存到列表中之前对其进行查询?

感谢您的建议:-)

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    我使用了一个很棒的功能populate解决了这个问题!

    dtryon 也是对的:您不需要在模型中声明您的 _id ObjectIds,它们无论如何都会被添加。而且你必须嵌套这些东西,因为你的任务是异步保存的,所以你必须确保它在其他东西之前运行。

    解决方法如下:

    架构:

    var TaskSchema = new Schema({
        title: String,
        list: { type: Schema.ObjectId, ref: 'list' }
    
    });
    
    var Task = mongoose.model('task', TaskSchema);
    
    var ListSchema = new Schema({
        title: String,
        tasks: [{ type: Schema.ObjectId, ref: 'task' }]
    });
    
    var List = mongoose.model('list', ListSchema);
    

    控制器/路由器:

    app.post('/lists/:list_id/tasks', function(req, res) {
    
        var listId = req.params.list_id;   
    
        var newTask = new Task();
        newTask.title = req.body.title;
        newTask.list = listId; 
    
    
        // WHEN SAVING, WRAP THE REST OF THE CODE
    
        newTask.save(function (err){
           if (err) {
                console.log('error saving new task');
                console.log(err);
            } else {
                console.log('new task saved successfully'); 
    
                list.findById(listId), function(err, doc){
    
                    doc.tasks.push(newTask);
    
                    doc.save(function (err){
                        if (err) {
                        console.log('error adding new task to list');
                        console.log(err);
                        } else {
    
                        console.log('new task saved successfully'); 
                        res.redirect('/lists/' + listId);
    
                        }  
                    });
                });
            });
        });
    });
    

    现在它可以正确引用并使用填充功能,您可以非常轻松地访问条目。像魅力一样工作:-)

    【讨论】:

      【解决方案2】:

      我认为这可能与异步有关。您可能看不到 ObjectId,因为您在推送 newTask 之前调用了 list.findById可能。此外,在异步操作之外执行res.redirect 也会遇到麻烦。

      试试这个:

      app.post('/lists/:list_id/tasks', function(req, res) {
      
              var listId = req.params.list_id;   
      
              // 1. Save the new task into the tasks-collection.
      
              var newTask = new Task();
              newTask.title = req.body.title;
              newTask.list = listId; 
      
              console.log('TaskId:' + newTask._id);  // Returns undefined on the console!!!
      
              // WHEN SAVING, WRAP THE REST OF THE CODE
              newTask.save(function (err){
                  if (err) {
                      console.log(err);
                          // do something
                  }
      
                  // 2. Add the new task to the coresponding list.
      
                  list.findById(listId, function(err, doc){
      
                      doc.tasks.push(newTask);
      
                      doc.save();  // Saves the new task in the list but WITHOUT its objectId
      
                      // REDIRECT AFTER SUCCESS
                      res.redirect('/lists/' + listId)
      
                  });
             });
      });
      

      【讨论】:

      • 我不明白你想用它来完成什么 :-( 但它也不起作用:仍然没有嵌入文档的 ObjectId...
      • 另外,如果你想生成一个,我不确定你是否需要在 Schema 上定义 _id。看看这个:stackoverflow.com/questions/6854431/…
      猜你喜欢
      • 2014-01-04
      • 1970-01-01
      • 1970-01-01
      • 2014-07-10
      • 1970-01-01
      • 2020-02-23
      • 1970-01-01
      • 2020-09-18
      • 2015-05-08
      相关资源
      最近更新 更多