0
votes

I have these schemas on my Mongo collection:

range = Schema
   name: { type: String }

category = Schema
    name: { type: String },
    range: { type: Schema.ObjectId, ref: 'range' }

product = Schema
    name: { type: String },
    category: { type: Schema.ObjectId, ref: 'category' }

(I omitted all the other fields for brevity)

What I need is to execute a find() that returns all the products which are chidren of a specific range. As a filter, I use the range _id.

db.product.find( { "category.range._id": ObjectID("XXXXXX") });

This one does not work, and neither

db.product.find( { "category.range": ObjectID("XXXXXX") });

what's the correct way to query sub-subdocuments by _id?

Note: _ids are autogenerated by mongo

Thanks in advance!

1

1 Answers

1
votes

You are suing a ref in mongoose, so 2 solution to get the product in a category :

First solution, one query aggregate stage $lookup :

Example, suppose you have this data :

in product:

{"_id":"5c951cf16726d70011f99adc","name":"p1","category":"c1Id"}

in category :

{"_id":"c1Id","range":"r1"}

To query the product from the other collection category :

db.category.aggregate([
  {$match: {range: 'r1'}}, 
  {$lookup: {from: "product", localField: "_id", "foreignField": "category", as: "product"}}
])

You will get :

{"_id":"c1Id","range":"r1","product":[{"_id":"5c951cf16726d70011f99adc","name":"p1","category":"c1Id"}]}

Second solution, use the mongoose virtuals :

You can perform it directly with mongoose.

You need to change your schema this way :

category = Schema
    name: { type: String },
    range: { type: Schema.ObjectId, ref: 'range' }

category.virtual('products', { ref: 'product', localField: _id", "foreignField": "category", justOne: false })


const category= await category.findOne({ _id: 'r1' }).populate('products');

// category.products will contains the products.