Mongoose Populate Virtuals with Multiple Local/Foreign Key Pairs
Asked Answered
M

2

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"]
});
Micturition answered 21/4, 2017 at 21:2 Comment(0)
N
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

Naturalize answered 15/8, 2018 at 12:43 Comment(0)
D
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
});

Doner answered 13/11, 2022 at 8:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.