user3081076
user3081076

Reputation: 57

Mongoose: Set field in schema using search query

So.. I was wondering if in Mongoose I could do something like this:

var Match = require('./models/Match);    

ClubSchema = new mongoose.Schema({
  _id: {type: String, required: true, unique: true},
  name: {type: String, required: true, unique: true},
  playedMatches: //Search query for played matches here (so like Match.find())
});

So I want the playedMatches field to be filled when I use a query to search a club. Right now I use sort of a "Singleton type way" to fill the playedMatches field like so:

ClubSchema.playedMatches = null;

ClubSchema.methods.setPlayedMatches = function (callback) {
  var self = this;
  Match.find({$or: [{homeClub: self._id}, {awayClub: self._id}], matchOver: true}).sort({playDate: 'asc'}).exec(function (err, matches) {
    if (err) {
      callback(err);
    } else {
      self.playedMatches = matches;
      callback(false, matches);
    }
  });
};

ClubSchema.methods.getPlayedMatches = function (callback) {
  if (!this.playedMatches) {
    this.setPlayedMatches(function (err, matches) {
      if (err) {
      callback(err);
      } else {
        callback(false, matches);
      }
    });
  } else {
    callback(false, this.playedMatches);
  }
};

But because I want things to go asynchronous that doesn't really work and I don't want to have to call a method to set the playedMatches field first before I use any other function that uses the playedMatches field cause well.. That's just ugly too..

the MatchSchema looks like this:

var MatchSchema = new mongoose.Schema({
  _id: {type: String, required: true, unique: true},
  homeClub: {type: String, ref: 'Club'},
  awayClub: {type: String, ref: 'Club'},
  playDate: {type: Date, required: true},
  goalsHomeClub: {type: Number},
  goalsAwayClub: {type: Number},
  matchOver: {type: Boolean, default: false}
});

Thnx in advance!

Upvotes: 0

Views: 560

Answers (1)

ZeMoon
ZeMoon

Reputation: 20284

Mongoose has an inbuilt way for this called populate.

All you need to do is mention the model name in the ref field of the field specification. The model name has to be the same as written in the Mongoose.model method.

ClubSchema = new mongoose.Schema({
  _id: {type: String, required: true, unique: true},
  name: {type: String, required: true, unique: true},
  playedMatches: [{type: ObjectId, ref: 'Match'}]
});

You can now populate the matches in the field automatically after a query with the following code:

Club.find({}).populate('playedMatches');

Upvotes: 2

Related Questions