Агрегировать схему goose и сохранить среднее значение в базе данных - PullRequest
0 голосов
/ 01 марта 2020

Работа над приложением узла одна из функций для пользователей для создания рецептов.

Используя почтальона, я успешно создаю, получаю и т. Д. c. Я хотел бы объединить оценки на RecipeSchema и просто рассчитать среднее значение, которое будет отображаться во внешнем интерфейсе, когда я начну строить это.

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

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const RecipeSchema = new Schema({
  user: {
    type: Schema.Types.ObjectId,
    ref: 'user'
  },
  name: {
    type: String,
    required: true
  },
  avatar: {
    type: String
  },
  title: {
    type: String,
    trim: true,
    required: [true, 'Please add a title for recipe']
  },
  description: {
    type: String,
    required: [true, 'Please add a description for recipe']
  },
  servings: {
    type: Number,
    required: [true, 'Please add number of servings recipe will make']
  },
  prepTime: {
    type: Number,
    required: true,
    min: 0,
    max: 59,
    required: true
  },
  cookTime: {
    type: Number,
    required: true
  },
  image: {
    type: String,
    default: 'no-photo.jpg'
  },
  ingredients: [
    {
      ingredient: {
        type: String,
        required: true
      },
      amount: {
        type: Number,
        required: true
      }
    }
  ],
  directions: [
    {
      step: {
        type: Number,
        required: true
      },
      direction: {
        type: String,
        required: true
      }
    }
  ],
  ratings: [
    {
      user: {
        type: Schema.Types.ObjectId,
        ref: 'users'
      },
      rating: {
        type: Number,
        min: 1,
        max: 10
      }
    }
  ],
  avgRating: {
    type: Number
  },
  comments: [
    {
      user: {
        type: Schema.Types.ObjectId,
        ref: 'users'
      },
      text: {
        type: String,
        required: true
      },
      name: {
        type: String
      },
      avatar: {
        type: String
      },
      date: {
        type: Date,
        default: Date.now
      }
    }
  ],
  date: {
    type: Date,
    default: Date.now
  }
});

Сначала я пытался использовать метод $ unwind mon goose, чтобы просмотреть рейтинги и попытаться получить среднее значение. Кажется, что с помощью '$ match', а затем '$ project' можно получить среднее значение, и я могу сохранить результат в console.log.

// Get the average recipe rating
RecipeSchema.statics.getAverageRating = async function(recipe) {
  const obj = await this.aggregate([
    {
      $match: { recipe: recipe }
    },
    {
      $project: {
        avgRating: { $avg: '$ratings.rating' }
      }
    }
  ]);

  try {
    console.log(
      `Average Rating for recipe ${obj[0]._id} is: ${obj[0].avgRating}`
    );
    await this.model('recipe').findByIdAndUpdate(recipe, {
      avgRating: obj[0].avgRating
    });
  } catch (err) {
    console.error(err);
  }
};

// Call getAverageRating after save
RecipeSchema.post('save', function() {
  this.constructor.getAverageRating(this.avgRating);
});

RecipeSchema.pre('remove', async function() {
  await this.constructor.getAverageRating(this.avgRating);
});

module.exports = mongoose.model('recipe', RecipeSchema);

Пост не обновляет базу данных. Любой совет по этому поводу?

Консоль после отправки нового рецепта в БД

{ id: '5e5bf09722a495afe703590e', iat: 1583083680, exp: 1585675680 }
Promise { <pending> }
POST /api/v1/recipes 201 421.186 ms - 1495
Average Rating for recipe 5e5bf809502395fe13da95c4 is: 7.333333333333333
[nodemon] restarting due to changes...
[nodemon] starting `node server.js`
Server is running in development mode on PORT:8080
MongoDB Connected cluster0-shard-00-00-6tjes.mongodb.net

...