Mongoose:引用自定义字段名称

Posted

技术标签:

【中文标题】Mongoose:引用自定义字段名称【英文标题】:Mongoose: ref custom field name 【发布时间】:2019-01-01 03:45:21 【问题描述】:

我正在配置 Mongoose 以在现有的 MongoDB 上工作,该 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);

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

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

user.org_id 将由组织数据填充。当然,我会更高兴在填充方法和路径(即user.organizationd)中同时使用organization 而不是org_id

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

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

【问题讨论】:

你可以试试$lookup聚合...***.com/questions/49953780/… 这能回答你的问题吗? How to rename path in response for populate 【参考方案1】:

我知道您不想更改现有文档,但对我来说,如果此字段名称没有更有意义的意义,您需要重构。

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

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

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

之后你可以调用.populate('organization')

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

Mongoose 文档:Aliases

【讨论】:

Obrigado,但正如我提到的,我不能这样做,因为我的系统不是唯一使用这个数据库的系统,我现在不能重构所有系统。【参考方案2】:

我会跟随你的代码。看起来你应用了这个: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 已经在 userSchema 中被引用。我们刚刚到达 org_id 属性并提取。这很简单。接下来在不更改 userSchema 和 organizationSchema 中的任何代码的情况下,我将通过虚拟属性找到哪个用户在哪个组织中。

虚拟属性允许我们在数据库中创建虚拟字段。它被称为虚拟,因为我们没有改变任何东西。这只是一种查看两个模型如何相关的方法。

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

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

非常简单优雅!

【讨论】:

以上是关于Mongoose:引用自定义字段名称的主要内容,如果未能解决你的问题,请参考以下文章

Mongoose 从其他字段创建自定义 _id

如何添加自定义字段和引用

使用 2 个字段的猫鼬自定义验证

使用 jira 中的 REST api 修改自定义字段名称后,CustomFieldManager 未获取自定义字段

Woocommerce REST API:自定义字段而不是产品名称

自定义validation注解:解决动态多字段联动校验问题