代码之家  ›  专栏  ›  技术社区  ›  Alexander

Mongoose:ref自定义字段名

  •  1
  • Alexander  · 技术社区  · 6 年前

    我正在配置Mongoose来处理现有的MunGDB,它有这两个集合:

    用户 -带字段:

    _id: ObjectId
    name: String
    org_id: ObjectId
    

    组织 -带字段:

    _id: ObjectId
    name: String
    

    我希望能够按组织数据填充用户文档。

    所以我创建了这两个模型:

    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);
    

    因为历史上,从用户到组织的ref字段被称为 org_id (而不是仅仅 organization )按组织代码填充用户是:

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

    哪里 user.org_id 将由组织数据填充。我当然更乐意 组织 而不是 组织id 在-populate方法和路径中(即。 user.organizationd ).

    在不改变现有文件的情况下,如何实现它?

    我可以创建我的模式方法(而不是填充)和别名,但我正在寻找一个更通用和优雅的解决方案。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Marcus Vinicius Sousa Vieira    6 年前

    我知道你不想改变现存的文档,但是对我来说,如果这个字段的名称没有意义,你需要重构。

    更改字段的名称,组织,而不是组织id。

    为此,您可以使用$rename命令: MongoDB $rename

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

    之后你可以打电话 .populate('组织') .

    如果不可能的话,我相信你不会找到比 别名 .

    猫鼬文件: Aliases

        2
  •  0
  •   Yilmaz    5 年前

    我将遵循您的代码。看起来您应用了以下内容: mongoose.Schema=Schema

    您将组织模型嵌入到用户中。首先让我们提取每个用户的组织详细信息。

    //导入用户和组织模型

    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)  }
    

    在上面的代码中,用户模式中已经引用了org_id。我们刚刚到达组织id属性并提取。这很简单。接下来,在不更改userSchema和organizationSchema中的任何代码的情况下,我将找到哪个用户在哪个具有虚拟属性的组织中。

    虚拟属性允许我们在数据库中创建虚拟字段。它被称为虚拟,因为我们不改变任何东西。这只是了解两个模型之间关系的一种方式。

    为此,我们将在定义organizationSchema文件的页面上添加一点代码,我假设该文件位于models/organization.js中。此代码将描述虚拟字段。这是一种虚拟领域的模式。

    //模型/组织.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
    })
    

    现在该编写函数来查找组织内部的用户了。

    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.
    }
    

    非常简单优雅!