2015-11-02 4 views
0

я в настоящее время работает в небольшой фирме в качестве стажера, и я работаю на пользователя схему, которая идет как это:обновление коллекции с мангуста после агрегации

var UserSchema = new Schema({ 
    name: String, 
    email: { 
     type: String, 
     unique: true 
    }, 
    username: { 
     type: String, 
     unique: true 
    }, 
    hashed_password: String, 
    provider: String, 
    salt: String, 

и из-за изменений на приложение, которое я работаю, я обновить эту схему в том, что:

var UserSchema = new Schema({ 
    name: String, 
    email: { 
     type: String, 
     unique: true 
    }, 
    username: { 
     type: String, 
     unique: true 
    }, 
    hashed_password: String, 
    provider: String, 
    salt: String, 


    stats : { 
     bricks: Number,// Number of bricks created by an user 
     layers: Number,// --------- layers ------------------ 
     projects: Number,//-------- projects ---------------- 
     lastogin: Date 
    }, 

}); 

конечно, есть бывшая версия приложения в Интернете, и мне нужно обновить все существующие пользователь в коллекции пользователя.

Для этого мне нужно подсчитать каждый кирпич/слои/проекты, созданные каждым пользователем. этого кирпич схема:

/************** 
App fields 
**************/ 

// False deletion field 
field.deleted = function() { 
    return field.bool(); 
}; 

// Creation date 
field.created = function() { 
    return field.date(); 
}; 

// Title Field 
field.title = function() { 
    return field.string(); 
}; 

// Desc Field 
field.desc = function() { 
    return field.string(); 
}; 

// Default short Id field 
field.shortId = function(id) { 
    return { 
    type: ShortId, 
    index: true, 
    len: 7,  // Length 7 characters 
    base: 64, // Web-safe base 64 encoded string 
    alphabet: "abcdefghijklmnopkrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", // Use default alphabet for base 
    retries: 4 // Four retries on collision 
    }; 
}; 

// The author of the content 
field.user = function() { 
    return { 
    user: field.ref('User'), 
    } 
}; 

field.favorites = function() { 
    return [{ 
    type: Schema.ObjectId, 
    ref: 'User' 
    }]; 
}; 

field.contributors = function() { 
    return [{ 
    type: Schema.ObjectId, 
    ref: 'User' 
    }]; 
}; 

field.comments = function() { 
    return [{ 
    // user that have written the comment 
    user: field.ref('User'), 
    // comment text it-self 
    comment: field.string() 
    }]; 
}; 

После некоторых исследований я решил использовать агрегацию трубопровод мангуста (и MongoDB) к группе кирпичей пользователями, используя, следующий запрос:

db.bricks.aggregate(
    [ 
     { 
      $group : { 
       _id : "$user", 
       count : { $sum : 1} 
     } 
    ] 
) 

и следующие методы с мангуста:

var promise =Brick.aggregate() 
     .group({ _id: "$user"}) 
     .exec(function (err, res) { 
      if (err) return handleError(err); 
      else { 
       console.log(res); 
      } 
     }); 

Я знаю, что ехес() мето ds возвращает promise, и я все еще изучаю его правильное использование.

После этого я хотел бы выполнить запрос на обновление для всех пользователей. Поскольку они не создали такое же количество кирпичей, я не могу сделать мульти обновления и мне нужно, чтобы петля на счет результатов с запросом, которые делают выглядеть следующим образом:

User.update({id : user_id}, {$set : {"stats.bricks" : Brick.find({user : user_id}).count()}}) 

Можно ли сделать это так или мне нужно переосмыслить эту проблему иначе

+0

Вы близки, но, к сожалению, '.exec()' не возвращает обещание. Опустите '.exec()', и у вас действительно есть обещание, из которого вы можете действовать по результатам. О, и этот последний пример кода, очевидно, заимствован из оболочки MongoDB, где то, что вы «думаете» происходит, не то, что действительно происходит. Как «синхронный» процесс, внутренние запросы запроса оцениваются до выполнения внешнего запроса. Может также быть статическим значением –

+0

Спасибо! Но в документах API-интерфейса mongoose написано, что .exec() возвращает обещание (ссылка на слово обещает перенаправление в документах API). Во всяком случае, я приостановил, что последний «запрос» не будет работать так, и я добавил в группу поле «count» (вы можете увидеть его в запросе mongoshell), чтобы получить количество элементов, созданных пользователем, а затем использовать это для обновления. –

+1

Хм. Thankyou первый плакат здесь когда-либо для того, чтобы фактически обратить внимание на то, кто только что дал вам хороший совет (нет!). Нет. '.exec()' специально требует «обратного вызова» в качестве аргумента. –

ответ

0

я пытался что-то еще и удался получить результат я хотел

exports.updatesUsersStats = function (req, res) { 
    User.find().exec(function(err, users) { 
    console.log(users.length); 
    _.each(users, function(currentUser) { 
     console.log("Count bricks user :" +currentUser._id); 
     Brick.find({user : currentUser._id}) 
     .exec(function(err, bricks) { 
      if(err) return handleError(err); 
      console.log("Update user :"+ currentUser._id); 
      User.update({_id : currentUser._id}, {$set : {"stats.bricks" : bricks.length}}) 
      .exec(function(err) 
      { 
       if(err) return handleError(err); 
      }); 
     }); 
    }); 
    res.jsonp({ 
     updateType : "updateUserStats", 
     operations : users.length 
    }); 
    }); 
}; 

Я откладывал агрегацию, которая принимает во внимание все пользователь (чей кто не создал контент).

Смежные вопросы