合并集合以获得平均评分,但在给出评级之前仍然可以获得所有原始集合。 Mongoose / nodejs

时间:2015-01-22 02:54:19

标签: javascript node.js mongodb mongoose

我有一个创建项目(波本威士忌)的管理员,用户可以在该评论中发表评论和评级。我能够汇总评论,但无法显示新创建的波旁威士忌,只有已经播种过已经有评分的那些。我试图实现与此主题类似的内容:referenced thread,但我没有做正确的事情。

我是一个菜鸟,主要是在前端玩,我对如何将这个示例代码更改为实际的生产代码感到非常困惑。我看到每个函数正在做什么,但仍然模糊不清。

我应该执行async.each并将聚合函数设置为迭代器吗?我知道这是破坏了。我现在尝试了一些事情。继续得到500错误,console.log上没有任何内容。对这个菜鸟的任何帮助,非常感谢。

这是我的架构: 波旁:

'use strict';

var mongoose = require('mongoose'),
    BourbonSchema = null;

module.exports = mongoose.model('Bourbon', {
    name:  {type: String, required: true},
    blog:  {type: String, required: true},
    photo: {type: String, required: true, default:'http://aries-wineny.com/wp-content/uploads/2014/09/woodford-reserve.jpg'},
    location: {type: String, required: true},
    distillery: {type: String, required: true},
    avgRating: {type: Number}
});

var Bourbon = mongoose.model('Bourbon', BourbonSchema);
module.exports = Bourbon;

评论:

    'use strict';

var mongoose = require('mongoose');

module.exports = mongoose.model('Comment', {
    bourbonId:   {type: mongoose.Schema.ObjectId, ref: 'Bourbon'},
    userId:   {type: mongoose.Schema.ObjectId, ref: 'User'},
    text:     {type: String, required: true},
    createdAt: {type: Date,  required: true, default: Date.now},
    rating  : {type: Number, required: true},
    votes:     {type: Number, default: 0}
});

这是我的控制器中的find / get,我尝试从引用的链接拼凑起来,但现在是slopp:

    'use strict';

var Bourbon = require('../../../models/bourbon'),
    Comment = require('../../../models/comment'),
    DataStore = require('nedb'),
    db = new DataStore(),
    async = require('async');

module.exports = {
    description: 'Get Bourbons',
    notes: 'Get Bourbons',
    tags: ['bourbons'],
    handler: function(request, reply){

        async.waterfall(
            [
                function(comment,callback){
                    async.series(
                        [

                            function(callback){
                                Bourbon.find({},function(err,results){
                                    async.eachLimit(results,10,function(result,callback){
                                        db.insert({
                                            'bourbonId': result._id.toString(),
                                            'location' : result.location,
                                            'blog'     : result.blog,
                                            'distillery': result.distillery,
                                            'name': result.name,
                                            'avgRating': 0
                                        },callback);
                                    },callback);
                                });
                            },

                            function(callback){
                                Comment.aggregate(
                                    [
                                        {'$group':{
                                            '_id': '$bourbonId',
                                            'avgRating':{
                                                '$avg':'$rating'
                                            }
                                        }}
                                    ],
                                    function(err,results){
                                        async.eachLimit(results,10,function(result,callback){
                                            db.update(
                                                {'bourbonId': result._id.toString()},
                                                {'$set':{
                                                    'avgRating': result.avgRating
                                                }
                                                },
                                                callback
                                            );
                                        },callback);
                                    }
                                );
                            }
                        ],
                    function(err) {
                        if (err) callback(err);
                        db.find({},{'_id': 0},callback);
                    }
                    );
                }
            ],
            function(err,results){
                reply({results: results});
                console.log('LOOOOOOOOOOOOOOOOK',JSON.stringify(results, undefined, 4));
                process.exit();
            });
    }
};

1 个答案:

答案 0 :(得分:0)

似乎你有更多关于回调和排序的知识。这是您需要的请求处理程序中的所有代码。当然,当您看到正在发生的事情时,更改为发送响应。

async.series(
  [
    // List out exiting collection with 0 average
    function(callback) {
      Bourbon.find({},function(err,results){
        async.eachLimit(results,10,function(result,callback){
          var plain = result.toObject()
          plain.bourbonId = plain._id.toString();
          plain.avgRating = 0;
          delete plain._id;

          db.insert(plain,callback); // next each iteration
        },callback);                  // move to next in series
      });
    },

    // Get aggregate results and update the items you just wrote
    function(callback) {
      Comment.aggregate(
        [
          { '$group': {
            '_id': '$bourbonId',
            'avgRating':{ '$avg':'$rating' }
          }}
        ],
        function(err,results) {
          async.eachLimit(results,10,function(result,callback){
            db.update(
              {  'bourbonId': result._id.toString() },
              {'$set': {'avgRating': result.avgRating } },
              callback                   // next each iteration
            );
          },callback);                   // next in series "last"  
        }
      );
    }
  ],
  // This is called when both in the series are complete
  function(err) {
    if (err) callback(err);
    db.find({},{'_id': 0},function(err,docs) {
        console.log( docs );
    });
  }
);

这里的目标是:

  1. 在所有项目的哈希表(此处使用nedb)中输入0值
  2. 从其他集合中获取聚合结果
  3. 使用实际具有值的项目更新所有项目的副本
  4. 完成所有操作后,您将回读哈希表

  5. 完整的工作示例:

    var async = require('async'),
        mongoose = require('mongoose'),
        DataStore = require('nedb'),
        db = new DataStore(),
        Schema = mongoose.Schema;
    
    var userSchema = new Schema({
      "name": String
    });
    
    var ratingSchema = new Schema({
      "bourbonId": { "type": Schema.Types.ObjectId, "ref": "Bourbon" },
      "userId": { "type": Schema.Types.ObjectId, "ref": "User" },
      "rating": { "type": Number, "required": true }
    });
    
    var bourbonSchema = new Schema({
      "name": { "type": String, "required": true },
      "blog": { "type": String, "required": true },
      "photo": { "type": String, "required": true },
      "ratings": [{ "type": Schema.Types.ObjectId, "ref": "Rating" }],
      "rating": { "type": Number }
    });
    
    var User = mongoose.model( "User", userSchema ),
        Rating = mongoose.model( "Rating", ratingSchema ),
        Bourbon = mongoose.model( "Bourbon", bourbonSchema );
    
    
    mongoose.connect("mongodb://localhost/bourbon");
    
    async.waterfall(
      [
        function(callback) {
          async.each([User,Rating,Bourbon],function(model,callback) {
            model.remove({},callback);
          },
          function(err) {
            callback(err);
          });
        },
    
        function(callback) {
          Bourbon.create({
            "name": 'test',
            "blog": 'test',
            "photo": 'test'
          },callback);
        },
    
        function(bourbon,callback) {
          Bourbon.create({
            "name": 'another',
            "blog": 'another',
            "photo": 'another'
          },callback);
        },
    
        function(bourbon,callback) {
          User.create({ "name": 'ted' },function(err,user) {
            if (err) callback(err);
            Rating.create({
              "bourbonId": bourbon,
              "userId": user,
              "rating": 5
            },function(err,rating1) {
              callback(err,user,bourbon,rating1)
            });
          });
        },
    
        function(user,bourbon,rating1,callback) {
          Rating.create({
            "bourbonId": bourbon,
            "userId": user,
            "rating": 7
          },function(err,rating2) {
            callback(err,bourbon,rating1,rating2);
          });
        },
    
        function(bourbon,rating1,rating2,callback) {
          Bourbon.findById(bourbon.id,function(err,bourbon) {
            bourbon.ratings.push(rating1,rating2);
            bourbon.save(function(err,bourbon) {
              callback(err)
            });
          });
        },
    
        function(callback) {
          async.series(
            [
              function(callback) {
                Bourbon.find({},function(err,results) {
                  if (err) callback(err);
                  async.eachLimit(results,10,function(result,callback) {
                    var plain = result.toObject();
                    plain.bourbonId = plain._id.toString();
                    plain.avgRating = 0;
                    delete plain._id;
    
                    db.insert(plain,callback);
                  },callback);
                });
              },
    
              function(callback) {
                Rating.aggregate(
                  [
                    { "$group": {
                      "_id": "$bourbonId",
                      "avgRating": { "$avg": "$rating" }
                    }}
                  ],
                  function(err,results) {
                    if (err) callback(err);
                    async.eachLimit(results,10,function(result,callback) {
                      db.update(
                        { "bourbonId": result._id.toString() },
                        { "$set": { "avgRating": result.avgRating } },
                        callback
                      );
                    },callback);
                  }
                );
              }
            ],
            function(err) {
              if (err) callback(err);
              db.find({},{ '_id': 0 },callback);
            }
          );
        }
    
      ],
      function(err,results) {
        if (err) throw err;
        console.log( results );
        mongoose.disconnect();
      }
    );
    

    按预期返回结果:

    [ { name: 'test',
        blog: 'test',
        photo: 'test',
        __v: 0,
        ratings: [],
        bourbonId: '54c17bea8aa5f8c9161f5b6e',
        avgRating: 0 },
      { name: 'another',
        blog: 'another',
        photo: 'another',
        __v: 1,
        ratings: [ [Object], [Object] ],
        bourbonId: '54c17bea8aa5f8c9161f5b6f',
        avgRating: 6 } ]