猫鼬:ref自定义字段名称

时间:2018-07-24 13:32:39

标签: node.js mongodb mongoose mongoose-schema

我正在配置Mongoose以在现有的MongoDB上工作,该数据库具有以下两个集合:

用户-带有字段:

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

由于历史上从用户到组织的引用字段称为org_id(而不只是organization),因此组织代码中的用户总数为:

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

其中user.org_id将由组织数据填充。当然,在填充方法和路径(即organization)中都使用org_id而不是user.organizationd会更快乐。

在不更改现有文档的情况下实现此目标的正确方法是什么?

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

2 个答案:

答案 0 :(得分:1)

我了解到您不想更改现有文档,但是对我来说,如果此字段名称没有任何意义,则需要进行重构。

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

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

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

此后,您可以呼叫 .populate('organization')

如果不可能,我相信您会找到比 aliases 更好的解决方案。

猫鼬文档:Aliases

答案 1 :(得分:0)

我将按照您的代码进行操作。看起来您应用了以下代码: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)  }
在上面的代码中,

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

虚拟属性允许我们在数据库中创建虚拟字段。之所以称为虚拟的,是因为我们什么都不会改变。这只是了解两个模型之间关系的一种方式。

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

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

现在是时候编写该功能以在组织内部查找用户了。

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

非常简单而优雅!