Mongoose save()在findOne()

时间:2016-03-26 20:09:18

标签: mongoose mongoose-schema

我正在使用Mongoose,Express和NodeJS实施审批系统。

每个帖子都有2套批准。

我已经实施了以下模型:

Post Schema:
var PostSchema = new Schema({
UserId: { type: ObjectId, unique: true, default: null },
/..
.. Object related fields
../
    Approval1: Object, //chidschema objects of approver
    Approval2: Object
});

Approval Mapping Schema:
var ApprovalMapSchema = new Schema({
  UserId: { type: ObjectId, unique: true, default: null },
  Approver1Id: { type: ObjectId, default: null },
  Approver2Id: { type: ObjectId, default: null }
});

我试图在我的函数中首先找到映射,然后在保存时更新主帖子对象。

我需要在保存新帖子之前检索两个批准者ID。

请建议一个很好的方法来解决它。我现在正在做:

  1. 保存新帖子对象,保存// 在第二步后返回,我知道 以异步方式保存在Mongoose中,但我不希望之前调用第2步 此
  2. 在ApprovalMapSchema上使用findOne获取审批者ID
  3. 使用审批者条目更新Post对象。

    post.save(function(err,doc){         if(err){}         其他         {             console.log({success:true,msg:'成功创建新帖子',content:doc});         }     });

    /*var actId = activation._id, distributorId, ttlId;
    
    var approvalMap = ApprovalMap.findOne({ userId: myUserId }, function(err, appMap) {
        if (err) throw err;
        else{           
            Approver1Id = appMap.Approver1Id;
            Approver2Id = appMap.Approver2Id;
        }
    });
    
    // Create child objects after this and update as subdocument
    
  4. 这对我不起作用。请帮助!

2 个答案:

答案 0 :(得分:1)

我很难理解你的问题。但听起来你想做这样的事情(你需要根据你想做的事情来修改它,但希望它能告诉你一种处理异步行为的方法):

    //This will run a query that returns a document where userId == myUserId

    ApprovalMap.findOne({ userId: myUserId }, function(err, appMap) {

        if (err) throw err;

        //Once the query is complete function(err, appMap) will be called
        //err will contain an error object if there was an error
        //appMap will be the data returned by the query.
        //within this block you can run another query
        //for example

        ApprovalMap.findOne({approved:'some variable'},function(err, secondQueryData){

            if (err) throw err;

            //after this query is complete function(err, secondQueryData) will be called
            //once again the err argument will be an error, and the 

            //secondQueyrData argument will contain your return data

            //here you can do something with the data
            //for example, log the results

            console.log(secondQueryData)
        })
    });

如您所见,您可以在其他查​​询的回调中嵌套其他查询或步骤。这将确保事情以正确的顺序运行。您可能还想查看npm异步库或q或bluebird等承诺库。他们还有一些很好的解决方案来处理节点中的异步行为。

答案 1 :(得分:0)

根据@ user2263572建议,去了异步库。

这就是我现在实现它的方式:

async.waterfall(
    [
        function(callback){
            ApprovalMap.findOne({ userId: myUserId }, function(err, appMap) {
                if (err) throw err;
                else{           
                    //..Create child approval elements and assign Ids from map
                    callback(err, Approver1Child, Approver2Child);
                }
            });
        },
        function(Approver1Child, Approver2Child, callback){
            var post = new Post(req.body);
            post.distApproval = Approver1Child;
            post.ttlApproval = Approver2Child;
            post.userId = myUserId;
            callback(null, post);
        }
    ], 
    function(err, post){
        //creating new order
        post.save(function(err, doc) {
            if (err) {
            }
            else
            {
                console.log({success: true, msg: 'Successful created new post', content: doc});
            }
        });
    }
);

非常感谢@ user2263572 !!干杯!