Mongoose: ref custom field name

99封情书 提交于 2021-02-10 17:52:37

问题


I am configuring Mongoose to work on an existing MongoDB, that has these two collections:

Users - with fields:

_id: ObjectId
name: String
org_id: ObjectId

Organizations - with fields:

_id: ObjectId
name: String

I want to be able to populate a User document by Organization data.

So I've created these two Models:

const userSchema = new Schema({
    name: String,
    org_id: {
        type: Schema.Types.ObjectId,
        ref: 'Organization',
    },
});
const User = mongoose.model('User', userSchema);

const organizationSchema = new Schema({
        name: String,
        code: String,
    });
const Organization = mongoose.model('Organization', organizationSchema);

Since historically the ref field from User to Organization is called org_id (instead of just organization) the population of a user by the organization code is:

const user = await User.findById('5b213a69acef4ac0f886cdbc')
    .populate('org_id')
    .exec();

where user.org_id will be populated by Organization data. Of course I would be happier to have organization instead of org_id in both - populate method and the path (i.e. user.organizationd).

What is the proper way to achieve it without changing the existing documents?

I could create my Schema methods (instead of populate) and aliases, but I am looking for a more generic and elegant solution.


回答1:


I understood that you don't want to change the existent documents, but for me, if this name of field doesn't make more sense you need to refactor.

Change the name of the field, organization instead of org_id.

For this you can use the $rename command: MongoDB $rename

 db.getCollection('users').updateMany({},{$rename: { "org_id": "organization" }});

After this you will can call .populate('organization').

If it is impossible, I believe that you will not find a solution better than aliases.

Mongoose Documentation: Aliases




回答2:


I will follow along your code.looks like you applied this: mongoose.Schema=Schema

you embedded Organization model into User. first lets extract organization details for each user.

//import User and Organization models

const main=async ()=>{
  const user=await User.findById("placeUserId")//we get the user
  const populated=await user.populate("org_id").execPopulate()//we populated organization with all properties
  console.log(populated.org_id)  }

in the above code, org_id was already referenced in the userSchema. we just reached org_id property and extracted. this was simple. next without changing any code in userSchema and organizationSchema i will find which user is in which organization with virtual property.

virtual property allows us to create virtual fields in the database. it is called virtual because we do not change anything. it is just a way that to see how two models are related.

for this we are gonna add a little code on the page where you defined you defined your organizationSchema file which i assume in models/organization.js. this code will describe the virtual field. it is kinda schema of the virtual field.

//models/organization.js

organizationSchema.virtual('anyNameForField',{
   ref:"User", //Organization is in relation with User 
   localField:"_id"//field that Organization holds as proof of relation
   foreignField:"org_id"//field that User holds as proof of relation
})

now time to write the function to find the user inside the organization.

const reverse=async ()=>{
    const organization=await Organization.findById("") 
    const populated=await organization.populate("anyNameForField").execPopulate()
    console.log(populated.anyNameForField) //i gave a stupid name to bring your attention.
}

very simple and elegant!



来源:https://stackoverflow.com/questions/51499983/mongoose-ref-custom-field-name

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!