FindOne mongoose nodejs的返回值

时间:2016-06-08 14:04:13

标签: node.js mongodb mongoose mongoose-schema

好吧,在用50种不同的方式尝试这个代码后,我正在敲打我的脑袋。

所以我有2v2的示例游戏,在每个游戏模式中玩家都会被用户和他们的用户名引用。

现在在游戏中,我想从这些用户那里获取评级并相应地更新它们,这必须同时发生。

我似乎无法抓住我的用户对象(来自长时间的Java,所以其中一些直接起来没有意义)。

如果可能的话,我想扩展它,所以一大堆嵌套的代码并不是我想要的。

没有进一步的诽谤:

gameSchema:

var gameSchema = mongoose.Schema({
    teamA_player1:      { type: String, ref: "userModel", required: true},
    teamA_player2:      { type: String, ref: "userModel", required: true},
    teamB_player1:      { type: String, ref: "userModel", required: true},
    teamB_player2:      { type: String, ref: "userModel", required: true},
    teamA_score:        { type: Number, required: true},
    teamB_score:        { type: Number, required: true}, 
    author:             { type: String, ref: "userModel", required: true},
    verification:       [{ type: String, ref: "userModel", required: true}],
    verified:           { type: Boolean},
    timestamp:          { type: Date}
});

userSchema:

var userSchema = mongoose.Schema({
    username:       { type: String, required: true, unique: true},
    password:       { type: String, required: true},
    firstName:      { type: String},
    lastName:       { type: String},
    about:          { type: String},
    email:          { type: String},
    clubs:          { type: [{type: ObjectId, ref: "clubModel"}]},
    games:          { type: [{type: ObjectId, ref: "gameModel"}]}, 
    rating:         { type: Number}
});

我的gameController中的代码问题:

updateRating = function(game){

    // The following code blob doesn't work and calling a_1.rating just gives Nan / undefined.
    var a_1 = users.findOne({username: game.teamA_player1});
    var a_2 = users.findOne({username: game.teamA_player2});
    var b_1 = users.findOne({username: game.teamB_player1});
    var b_2 = users.findOne({username: game.teamB_player2});

    var a_rating_old = (a_1.rating+a_2.rating)/2;
    var b_rating_old = (b_1.rating+b_2.rating)/2;

    var a_rating_new = 0;
    var b_rating_new = 0;

    if(game.teamA_score>game.teamB_score){
        a_rating_new = ratingChange(a_rating_old, b_rating_old, true);
        b_rating_new = ratingChange(b_rating_old, a_rating_old, false);
    }else{
        a_rating_new = ratingChange(a_rating_old, b_rating_old, false);
        b_rating_new = ratingChange(b_rating_old, a_rating_old, true);
    }

    var a_rating_change = a_rating_new - a_rating_old;
    var b_rating_change = b_rating_new - b_rating_old;

    a_1.rating += Math.round(a_rating_change * (a_rating_old/a_1.rating));
    a_2.rating += Math.round(a_rating_change * (a_rating_old/a_2.rating));
    b_1.rating += Math.round(b_rating_change * (b_rating_old/b_1.rating));
    b_2.rating += Math.round(b_rating_change * (b_rating_old/b_2.rating));

    a_1.save();
    a_2.save();
    b_1.save();
    b_2.save();

}

所以基本上我想知道在这里获取我的用户的正确方法是什么,提取他们的评级,更新它然后用新的评级保存用户(游戏本身不会发生任何变化)。

代码也可以在这里找到:https://github.com/mathieudevos/pinkiponki

2 个答案:

答案 0 :(得分:0)

因此,假设您已经在用户变量中需要模型,那么您做错的事情就是您将该函数分配给变量(例如a_1),当您需要通过时回调函数,然后将该回调的用户分配给变量。

这样的事情:

user.findOne({username: game.teamA_player1}, function(err, user){
  if(err) throw err;
  a_1 = user;
});

我建议您将需要模型的变量名称从用户更改为用户。

你可以看到我传递的回调函数有一个错误对象和一个用户对象,最后一个是你的信息存储的位置,来自db的对象,所以你应该将它的值赋给变量你想要的,在这种情况下是a_1。

请告诉我它是否成功了!

答案 1 :(得分:-1)

好吧,似乎在尝试这个问题时我有很多错误的想法。

主要问题是我没有考虑所有数据库查询都运行异步的事实,这引起了巨大的麻烦。

现在选项A是将它们全部嵌套在一起,最终形成一个巨大的代码blob /意大利面条,而不是真正的粉丝。特别是因为如果我想继续写这个应用程序,它不是很好。

因此,对于选项b,安装模块deasync和#DealWithIt

现在代码如下:

        protected override void OnStart(string[] args)
        {
            try
            {
                genLogs.WriteErrorLog("Service Started OnStart.");
                //int tmStart = Convert.ToInt32(ConfigurationManager.AppSettings["tim"]);
                using (Timer timer = new Timer(30000))  //  (1000 * 5 * 60) for 5 minutes
                {
                    timer.Elapsed += timer_Elapsed;
                    timer.Start();
                    //Console.WriteLine("Timer is started");
                    genLogs.WriteErrorLog("Timer is started.");
                    //Console.ReadLine();
                }
            }
            catch (Exception ex)
            {
                genLogs.WriteErrorLog("OnStart Service Error: " + ex.Message);
            }

        }

        void timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            try
            {
                genLogs.WriteErrorLog("Service Started Checking Windows Services and Web AppPools.");

                serviceLogic.InsertStatus();

                genLogs.WriteErrorLog("Service Calls Send SendEmails Method.");
                serviceLogic.SendInfo();
            }
            catch (Exception ex)
            {
                genLogs.WriteErrorLog("OnStart Service Error: " + ex.Message);
            }
        }