node.js - is it possible to check whether the user-given foreignFieldId (req.body.foreignFieldId ) exists or not before calling

admin2025-04-19  0

Product Schema:

const productSchema = new mongoose.Schema({
   name: { type: String, required: true },
   price: { type: Number, required: true },
   addedBy: { type: mongoose.Types.ObjectId, ref: 'User' },
   categoryId: { type: mongoose.Types.ObjectId, ref: 'Category' }, //holds the id **AFTER** creation
   isDeleted: { type: Boolean, default: false },
},
{ 
   timestamps: true,
   versionKey: false 
});

Category Schema:

const statusEnum = ["active", "inactive"]

const categorySchema = new mongoose.Schema({
   name: { type: String, required: true },
   status: { type: String, enum: statusEnum, default: "active" },
   isDeleted: { type: Boolean, default: false },
}, 
{
   timestamps: true,
   versionKey: false
});

I want to check, before creating a new entry in my MongoDB database, if a category in categories collection exists with the user given categoryId.

Is it possible using an aggregation, because I don't want to import the CategoryModel into my ProductControlller?

Product Schema:

const productSchema = new mongoose.Schema({
   name: { type: String, required: true },
   price: { type: Number, required: true },
   addedBy: { type: mongoose.Types.ObjectId, ref: 'User' },
   categoryId: { type: mongoose.Types.ObjectId, ref: 'Category' }, //holds the id **AFTER** creation
   isDeleted: { type: Boolean, default: false },
},
{ 
   timestamps: true,
   versionKey: false 
});

Category Schema:

const statusEnum = ["active", "inactive"]

const categorySchema = new mongoose.Schema({
   name: { type: String, required: true },
   status: { type: String, enum: statusEnum, default: "active" },
   isDeleted: { type: Boolean, default: false },
}, 
{
   timestamps: true,
   versionKey: false
});

I want to check, before creating a new entry in my MongoDB database, if a category in categories collection exists with the user given categoryId.

Is it possible using an aggregation, because I don't want to import the CategoryModel into my ProductControlller?

Share edited Mar 4 at 22:07 jQueeny 8,7853 gold badges6 silver badges28 bronze badges asked Mar 4 at 7:31 Avijit SenguptaAvijit Sengupta 133 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

It is possible to do this using an aggregation but it is really a hack/workaround when there is a clear solution - use the CategoryModel to query first.

Nonetheless, in case you are simply testing the efficiency of different approaches, with Model.aggregate() the logical steps might be:

  1. Query the database to retrieve any Product. It doesn't matter which document is returned we just need a single document to act as the host.
  2. $set a new field on that document named test_id using the user supplied categoryId from the request.
  3. Perform a $lookup on the categories collection matching on the new test_id field.
  4. Use an $unwind stage to unwind the array of objects that were assigned to test_id. If there was a match, $unwind will leave a single document - confirming that the categories collection has a document with that _id.
  5. If there wasn't a match the test_id field will be an empty array and given that:

$unwind does not output a document if the field value is null, missing, or an empty array.

You would therefore be left with zero documents - confirming that the categories collection doesn't have a document with that _id.

It might look like this:

const docs = await ProductModel.aggregate([
  {
    $sort: { _id: 1 }
  },
  {
    $limit: 1
  },
  {
    $set: {
      test_id: mongoose.Types.ObjectId.createFromHexString(req.body.categoryId)
    }
  },
  {
    $lookup: {
      from: "categories",
      localField: "test_id",
      foreignField: "_id",
      as: "test_id"
    }
  },
  {
    $unwind: "$test_id"
  }
])

if(docs.length){
   // A document does exists with that categoryId 
   // so free now to do a ProductModel.create()
}else{
   // docs is an empty array so there was no document with categoryId
   // need to return an error or whatever
}

Note: the $unwind stage isn't quite necessary. You could simply check for if(docs.test_id.length) but I feel leaving an empty docs array is somewhat more conclusive semantically and this solution isn't something that I would recommend over just checking using the CategoryModel.

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1745057281a282478.html

最新回复(0)