2

I've seen many examples about mongoose and relations, but how can I create a reference to another entity into a custom field ?

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
mongoose.connection.once('open', function(){

  var Author = m.model('Author', new m.Schema({
    name: String,
    slugname: String
  }));
  var Book = m.model('Book', new m.Schema({
    title: String,
    author: {type: String, ref: 'Author.slugname'}
  }));

});

In the code above, I'm linking Book.author into Author.slugname. it is just that I don't if this is the right way to do it.

alexserver
  • 1,348
  • 3
  • 15
  • 30
  • Possible duplicate of [Populate a mongoose model with a field that isn't an id](http://stackoverflow.com/questions/19287142/populate-a-mongoose-model-with-a-field-that-isnt-an-id) – Maxime Pacary Oct 05 '16 at 21:32

3 Answers3

5

No, you can't. Mongoose always use _id field to link documents. But...

You can set your own _id for each document, using any datatype you want. There are only two restrictions:

  • it should be unique
  • it should not be changed during document's lifetime

So, instead of adding new slugname field, use author's _id as a slugname:

var Author = m.model('Author', new m.Schema({
  _id: String, // <-- slugname
  name: String
}));
var Book = m.model('Book', new m.Schema({
  title: String,
  author: { type: String, ref: 'Author' }
}));
Leonid Beschastny
  • 50,364
  • 10
  • 118
  • 122
5

This is supported since Mongoose 4.5, and is called virtuals population.

Check my detailed answer on this (nearly duplicate) question.

Community
  • 1
  • 1
Maxime Pacary
  • 22,336
  • 11
  • 85
  • 113
1

Mongoose is set up more for direct object relations. Rather than linking your Book object to a slug for the Author object, it would suit better to link to the Author's _id property automatically created by Mongoose.

var Author = mongoose.model('Author', new mongoose.Schema({
    name: String
});
var Book = mongoose.model('Book', new mongoose.Schema({
    title: String
    author: { type: mongoose.Schema.Types.ObjectId, ref: 'Author' }
});

You can then save an Author as the author of the Book object by either saving book.author = author or book.author = author._id. Mongoose will automatically serialize the data when saving.

var author = new Author();
author.name = 'Hank Brekke';

var book = new Book();
book.title = 'My Book';
book.author = author;

book.save();

When pulling the book object, you can have Mongoose automatically populate the author property, which by default it will not, by adding the .populate('author') modifier before calling .exec()

Book.findOne({ /* query */}).populate('author').exec(function(error, book) {
    var author = book.author;
});

References:

http://mongoosejs.com/docs/populate.html

Hank Brekke
  • 2,024
  • 2
  • 24
  • 33