Get related items in keystone Get related items in keystone mongoose mongoose

Get related items in keystone


As far as I understand, keystone's List Relationship has nothing to do with mongoose and querying. Instead, it is used by keystone's admin UI to build out the relationship queries before rendering them in the view. This said I would forget User.relationship(...); solving your problem, although you want it for what I just mentioned.

The following should work fine based on your schema, but only populates the relationship on the one side:

var keystone = require('keystone');keystone.list('Post').model.findOne().populate('author', function (err, doc) {  console.log(doc.author.name); // Joe  console.log(doc.populated('author'));  // '1234af9876b024c680d111a1' -> _id});

You could also try this the other way, however...

keystone.list('User').model.findOne().populate('posts', function (err, doc) {  doc.posts.forEach(function (post) {    console.log(post);  });});

...mongoose expects that this definition is added to the Schema. This relationship is added by including this line in your User list file:

User.schema.add({ posts: { type: Types.Relationship, ref: 'Post', many: true } })

After reading the keystone docs, this seems to be logically equivalent the mongoose pure way, User.schema.add({ posts: [{ type: Schema.Types.ObjectId, ref: 'Post' }] });. And now you are now maintaining the relationship on both lists. Instead, you may want to add a method to your keystone list.

User.schema.methods.posts = function(done){  return keystone.list('Post').model.find()    .where('author', this.id )    .exec(done);};

By adding a method to your User list, it saves you from persisting the array of ObjectIds relating the MongoDB document back to the Post documents. I know this requires a second query, but one of these two options look to be your best bet.


I found this on their github https://github.com/Automattic/mongoose/issues/1888, check it for context, but basically says to use the keystone populateRelated() method. I tested it and does work

// if you've got a single document you want to populate a relationship on, it's neaterCategory.model.findOne().exec(function(err, category) {  category.populateRelated('posts', function(err) {    // posts is populated  });});

I'm aware the question is old but this has to be out there for further reference