Home > Mobile >  How to refer to a sub collection from another collection in MongoDB/Mongoose?
How to refer to a sub collection from another collection in MongoDB/Mongoose?

Time:01-15

I have a collection in mongo, let's call it Parent, with a property called children, something like this

const ParentSchema = mongoose.Schema({
children: [{
//children properties
}],
//other collection properties

When I save a record in this collection, every child gets an objectId like this

"_id" : ObjectId("63ba8421f2f128e2f8e6916d")

Then I have a collection called Report. In this collection I can refer to Parent like this

const ReportSchema = mongoose.Schema({
    parent: {
        type: mongoose.Schema.Types.ObjectId,
        ref: "Parent",
        required: false
    },

is there a way to define in this collection a field that refers to children, in order to create a record referring to a specific child? Or should I just use a string field and store the child id in there?

The idea would be to endup with records in Report like

{
    "_id" : ObjectId("63bc482afde665158cd71a41"),
    "createdBy" : ObjectId("63b9d635e6225fa0ff29f316"),
    "parent" : ObjectId("63bbac19fde665158cd718e9"),
    "child" : ObjectId("63ba83eef2f128e2f8e69140"),
// other properties
}

CodePudding user response:

Mongoose's ref property won't work for this, since it takes a model name, a Model, or a function that returns a model name or model but you aren't modeling children (doing so would imply storing them in a separate collection, not as an array on parent documents).

You can still just have a childId field of ObjectId type and put the child's ID there (you said string, but ObjectId is more appropriate) without declaring it as a ref, i.e.

const ReportSchema = mongoose.Schema({
  parent: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "Parent",
    required: false
  },
  child: mongoose.Schema.Types.ObjectId,
}

However you wouldn't be able to populate() the child field since mongoose's populate features would require there to be a separate Child model/collection.

You would of course be able to populate the parent field, then write code to pull the child document out of the populated parent's children array. You could also write a custom aggregation pipeline to do this on the DB side of the wire.

But your best best may be to bite the bullet and make a ChildSchema, a Child model, use that as a ref in Parent's children array, and then you can also use it as a ref for a child field in ReportSchema and mongoose's population features will work for it.

CodePudding user response:

For good practice, I'll prefer add ParentId in the Report Schema no need to store the all child id in the parents

if data will be large it may create issue..

const ParentSchema = mongoose.Schema({
//other collection properties
})

const ReportSchema = mongoose.Schema({
    parent: {
        type: mongoose.Schema.Types.ObjectId,
        ref: "Parent",
        required: true
    },
    
    // other keys
  })

  • Related