0

I'm working with Mongoose models and references. I've been using the code from mongoose's website where it talks about the populate method and references. I am trying to have it save the respective "referenced" ids in both models. It is only saving the reference ids in the story model. Here is the code:

Update: Added schemas at the top to help:

    var personSchema = Schema({
      _id: Schema.Types.ObjectId,
      name: String,
      age: Number,
      stories: [{ type: Schema.Types.ObjectId, ref: 'Story' }]
    });

    var storySchema = Schema({
      author: { type: Schema.Types.ObjectId, ref: 'Person' },
      title: String,
      fans: [{ type: Schema.Types.ObjectId, ref: 'Person' }]
    });

    var Story = mongoose.model('Story', storySchema);
    var Person = mongoose.model('Person', personSchema);

(end of schemas)

var author = new Person({
  _id: new mongoose.Types.ObjectId(),
  name: 'Ian Fleming',
  age: 50
});

author.save(function (err) {
  if (err) return handleError(err);

  var story1 = new Story({
    title: 'Casino Royale',
    author: author._id    // assign the _id from the person
  });

  story1.save(function (err) {
    if (err) return handleError(err);
    // thats it!
  });
});

When you run this code, it generates this in mongo:

  db.people.find()
  { "_id" : ObjectId("5be0a37f1dd61a343115e2c8"), "stories" : [ ], "name" : "Ian Fleming", "age" : 50, "__v" : 0 }
  db.stories.find()
  { "_id" : ObjectId("5be0a37f1dd61a343115e2c9"), "title" : "Casino Royale", "author" : ObjectId("5be0a37f1dd61a343115e2c8"), "__v" : 0 }

It appears to not be storing any ids in the people collection within "stories." Wouldn't you want to save the stories ids in the people collection as well?

I tried to modify the code to make it work with (moved the author save function, until after the story id is set):

 var author = new Person({
  _id: new mongoose.Types.ObjectId(),
  name: 'Ian Fleming',
  age: 50
 });

  var story1 = new Story({
    _id: new mongoose.Types.ObjectId(),
    title: 'Casino Royale',
    author: author._id    // assign the _id from the person
  });

  author.stories = story1._id;

  author.save(function (err) {
  if (err) return handleError(err);

  story1.save(function (err) {
    if (err) return handleError(err);
    // thats it!
  });

This gives me an author undefined.

seoandcode
  • 13
  • 1
  • 3

1 Answers1

0

Mongo wouldn't automatically add to the Person "stories" field just because you added a Story object.

You don't really need to store the story ids in Person objects anyway, as you can always get a list of stories by an author with

db.stories.find({author: <id>})

Storing in both places would create redundant information and you'd have to pick one to be the truth in the case of a mismatch. Better to not duplicate, methinks.

UPDATE:

References appear to help you populate referenced fields in queries automatically. According to this post you can retrieve an author and their stories like this:

db.persons.find({_id: <id>}).populate('stories')

Haven't personally used this but it looks pretty handy.

Mongoose docs for populate: https://mongoosejs.com/docs/populate.html

Jim B.
  • 4,512
  • 3
  • 25
  • 53
  • That makes sense... they do include a "stories" property in the Person schema. I wonder if that is just for reference (no pun intended) and not actually needed, in this particular case. I'll add their schema to the question. – seoandcode Nov 05 '18 at 22:37
  • Perhaps what "they" are doing is explained here: https://stackoverflow.com/questions/18001478/referencing-another-schema-in-mongoose – Jim B. Nov 06 '18 at 01:23