Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mongoose - ObjectId that references a Sub-Document

Would it be possible for an ObjectId in ModelA to reference a sub-document in modelB?

var C = new Schema({...});  
var B = new Schema({c: [C]});  
var A = new Schema({c: { type: ObjectId, ref: 'ModelB.ModelC' });  

var Model_A = mongoose.model('ModelA', A);  
var Model_B = mongoose.model('ModelB', B);  
var Model_C = mongoose.model('ModelC', C);  
like image 484
Shakirullahi Logico Avatar asked Jul 20 '14 18:07

Shakirullahi Logico


People also ask

Can a document have a sub document in MongoDB?

In Mongoose, subdocuments are documents that are nested in other documents. You can spot a subdocument when a schema is nested in another schema. Note: MongoDB calls subdocuments embedded documents.

What is Mongoose types ObjectId?

A SchemaType is different from a type. In other words, mongoose.ObjectId !== mongoose.Types.ObjectId . A SchemaType is just a configuration object for Mongoose. An instance of the mongoose.ObjectId SchemaType doesn't actually create MongoDB ObjectIds, it is just a configuration for a path in a schema.

Can I use $in in Mongoose?

For example, if we want every document where the value of the name field is more than one value, then what? For such cases, mongoose provides the $in operator. In this article, we will discuss how to use $in operator. We will use the $in method on the kennel collection.

How does Ref work in Mongoose?

The ref option is what tells Mongoose which model to use during population, in our case the Story model. All _id s we store here must be document _id s from the Story model. Note: ObjectId , Number , String , and Buffer are valid for use as refs.


2 Answers

Yes it is possible, but you have a few options.


Option 1: C as a Subdocument

If you really want to use subdocuments, you don't need to create a separate model. You need to change your reference to the 'c' array.

var C = new Schema({...});  
var B = new Schema({c: [C]});  
var A = new Schema({c: { type: ObjectId, ref: 'ModelB.c' });  

var Model_A = mongoose.model('ModelA', A);  
var Model_B = mongoose.model('ModelB', B); 

Option 2: C as a Model

(I only present this as an alternative - since your example seems redundant since you create 'C' as a separate Model as well as a subdocument)

Alternatively, it may make sense to have separate collections, you can create a mongoose model for each. Each will be a separate collection:

var Model_A = mongoose.model('ModelA', A);  
var Model_B = mongoose.model('ModelB', B);  
var Model_C = mongoose.model('ModelC', C);

In this case you may want to directly reference each model:

var C = new Schema({...});  
var B = new Schema({c: { type: ObjectId, ref: 'ModelC' }});  
var A = new Schema({c: { type: ObjectId, ref: 'ModelC' }); 

The Point

Yes its possible, but you need to pick if you want C as a model or subdocument.

like image 66
bkapicka Avatar answered Oct 30 '22 13:10

bkapicka


It's been 7 years but I faced the same issue, I found the plugin mongoose-sub-references-populate to populate subdocuments.

const subReferencesPopulate = require('mongoose-sub-references-populate');

var B = new Schema({c: [C]});  
var A = new Schema({c_inA: { type: ObjectId, subRef: 'ModelB.c' });  

A.plugin(subReferencesPopulate);
var Model_A = mongoose.model('ModelA', A);  
var Model_B = mongoose.model('ModelB', B);  

Model_A.findById(_id,async (error, res)=>{
  await res.subPopulate('c_inA');
  console.log(res);
})
like image 34
Trong Nghia Avatar answered Oct 30 '22 12:10

Trong Nghia