7

I've just discovered Mongoose's Populate Virtuals method, and it's going to save me a ton on my current project. I'm looking to extend it even further, though. Is there an easy way to populate based on multiple local/foreign key pairs? Here's an example of what the code might look like (Note: this is probably not a great example, but hopefully it conveys the basis of my question).

var workerSchema = new Schema({
    name: String,
    locationCode: String,
    departmentCode: String
});

var deparmentSchema = new Schema({
    locationCode: String,    //Note: neither location nor code
    code: String,            //are unique, but the combination of them are
    manager: String,
    otherInfoAboutDepartment: String
});

workerSchema.virtual('department', {
    ref: "Department",
    localField: ["locationCode", "departmentCode"],
    foreignField: ["locationCode", "code"]
});
anothermh
  • 9,815
  • 3
  • 33
  • 52
Justin
  • 161
  • 1
  • 8

2 Answers2

0

Though this may not be the answer you are looking for. You can get the workaround like this

workerSchema.virtual('department1',{
   ref: "Department",
   localField: "locationCode",
   foreignField: "locationCode"
})

workerSchema.virtual('department2',{
    ref: "Department",
    localField: "departmentCode",
    foreignField: "code"
})

In the find query you can use something like

Worker.find({}).populate('department1').populate('department2')

While processing the data you can check if the data field is empty or not and merge the two outputs into one

Ujjwal Nepal
  • 546
  • 5
  • 13
0

You could use the match function introduced in Mongoose 5.5 see here

It adds adds an extra filter condition to the query Mongoose uses to populate()


const workerSchema = new Schema({
  name: String,
  locationCode: String,
  departmentCode: String,
});

const departmentSchema = new Schema({
  locationCode: String, //Note: neither location nor code
  code: String, //are unique, but the combination of them are
  manager: String,
  otherInfoAboutDepartment: String,
});

workerSchema.virtual("department", {
  ref: "Department",
  localField: "departmentCode",
  // It will reference to departmentCode -> code in Department 
  foreignField: "code",
  //We can use the match option to filter the results based on the
  //parent document. In this case, we only want to return the
  //department if the locationCode matches the parent document's locationCode.
  match: (doc) => ({ locationCode: doc.locationCode }),
  justOne: true
});

Elvin Chu
  • 150
  • 1
  • 8