0

I am currently using mongoose v4.10.8 and am attempting to populate multiple arrays on a defined model.

TransportModel.js

//Transport model
'use strict';
const mongoose = require('mongoose');

const TransportSchema = new mongoose.Schema({
    tag: {
        type: String,
        enum: ['X', 'Y'],
        required: true,
        unique: true
    },
    chairs: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: "Chair"
    }],
    targets: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: "Target"
    }]
});

module.exports = mongoose.model('Transport', TransportSchema);

ChairModel.js

//Chair model
'use strict';
const mongoose = require('mongoose');

const ChairSchema = new mongoose.Schema({
    product_name: {
        type: String,
        required: true,
        unique: true
    },
    description: {
      type: String,
      unique: false,
      required: false
    }
});

module.exports = mongoose.model('Chair', ChairSchema);

TargetModel.js

//Target model
'use strict';
const mongoose = require('mongoose');

const TargetSchema = new mongoose.Schema({
    target_name: {
        type: String,
        required: true,
        unique: true
    },
    location: {
      type: String,
      required: true,
      unique: false
    },
    description: {
      type: String,
      unique: false,
      required: false
    }
});

module.exports = mongoose.model('Target', TargetSchema);

After having the above configuration in place, I created one Chair document and one Target document.

Afterwards, I invoke the following logic on a route to get a single Transport document:

TransportModel.findOne({
        tag: 'X'
    })
    .populate("chairs")
    .populate("targets")
    .exec(function(err, transport) {
        if (err) {
            console.error(err);
        }
        console.log('Transport: ', transport);
    });
});

Below is the retrieved document:

{
    "_id": "xxxx9999xxxx9999xxxx9999",
    "tag": "X",
    "__v": 1,
    "chairs": [],
    "targets": []
}

Thus, even though I queried the Chairs and Targets collections and I do have at least 1 document, the Transport document does not get populated.

Furthermore, I also tried the enhanced version of .populate(), but I keep getting empty arrays:

.populate({
  path: "chairs",
  model: "Chair"
})
.populate({
  path: "targets",
  model: "Target"
})
7
  • How did you add the Chair and Target documents to the TransportModel document? Commented Jul 15, 2017 at 12:21
  • Thank you for your reply, @robertklep. That is what I am trying to achieve with .populate(), I want the chairs and targets arrays of the Transport documents to be automatically populated with the entire available list of Chair and Target documents from their respective collections. Commented Jul 16, 2017 at 7:53
  • That's not what population does, though. It's a means to associate particular documents across collections. In other words, you have to manually associate a new Chair document with a TransportModel document. The .populate() method will then add the associated documents automatically during queries. See the documentation: mongoosejs.com/docs/populate.html Commented Jul 16, 2017 at 7:56
  • Thank you for your quick reply. If I understood correctly, it means I first have to push all the _id values associated with Chair documents in the chairs array, and afterwards .populate() simply brings the rest of the document properties from the chairs collection? That means that I still have to fire .find({}) query and push the chairs to the chairs array? Commented Jul 16, 2017 at 8:00
  • If by the last line you mean that you already have lots of chairs and want to add them to a TransportModel document, then yes. But if you want to associate all chairs and targets with a particular TransportModel document, population doesn't really seem to make sense, and you probably should run three different queries (one for each collection/model). Commented Jul 16, 2017 at 8:02

1 Answer 1

-1

If you already push the new chairs and targets into the Transport model, you can populate it better with the mongoose-deep-populate module, here is a simple example of how config to set it up.

var mongoose = require('mongoose');
var deepPopulate = require('mongoose-deep-populate')(mongoose);

var Schema = mongoose.Schema;

var kindsSchema = new Schema({

    name:{type:String,required:true,unique:true},
    components:[{type:Schema.ObjectId,ref:'components'}],
    associatedView:{type:String,default:'home/fragances'},
    discount:{type:Number,default:0},
    description:{type:String,default:'Nueva categoria'},

    created_at:{type:Date,default:Date.now},
    modified_at:{type:Date,required:true}
});

kindsSchema.plugin(deepPopulate,{
  whitelist:[
    'components.attributes',
  ]
    populate:{
      'components':{
      select['attributes','discount']
      }
    }
});

https://www.npmjs.com/package/mongoose-deep-populate

Sign up to request clarification or add additional context in comments.

1 Comment

Why would this be better?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.