2015-11-05 98 views
0

这个问题是类似于猫鼬架构:this question如何引用已尚未注册

与猫鼬的工作,我有一些像下面的代码。 (我用数字前缀了文件,所以我可以按照它们出现在“模型”目录中的顺序加载它们,但仍然控制加载顺序。)

在100-employee.server.model.js中:

var mongoose = require('mongoose'), 
    Schema = mongoose.Schema; 

var EmployeeSchema = new Schema({ 
    name: { 
    type: String, 
    default: '' 
    }, 
    company: { 
    type: Schema.ObjectId, 
    ref: 'Company' 
    }, 
    subordinates: [EmployeeSchema], 
}); 
mongoose.model('Employee', EmplyeeSchema); 

然后,在200公司server.js,我有:

var mongoose = require('mongoose'), 
    Schema = mongoose.Schema; 

var CompanySchema = new Schema({ 
    name: { 
    type: String, 
    default: '' 
    }, 
    CEO: { 
    type: Schema.ObjectId, 
    ref: 'Employee' 
    } 
}); 
mongoose.model('Company', CompanySchema); 

显然,这是不行的,因为它是注册公司之前引用。而且,以相反的顺序加载这些文件也不会出于同样的原因。我需要的,就像是一个逻辑数据结构:

{ 
    name: 'Acme, Inc', 
    CEO: { 
    name: 'Karen', 
    subordinates: [{ 
     name: 'Bob', 
     subordinates: [{ 
     name: 'Lisa', 
     subordinates: [] 
     }, 
     name: 'Jerry', 
     subordinates: [] 
     }] 
    }] 
    } 
} 

(我想我得到了我所有的括号内的地方,我刚才输入的是JSON说明的必要。)

我可以只使用一个EmployeeSchema中'公司'的ObjectId,但它不能解决问题。我仍然收到公司尚未注册的投诉。

有人会问的使用情况,所以在这里它是:

我有一堆companies.I有一个公司的雇员的层次结构。而且,我有很多公司。对于每家公司,我都需要了解首席执行官,而不必搜索我的所有员工,找到没有父母的员工,该公司拥有ObjectId ref公司,但这仍然会遇到同样的问题。

有什么建议吗?

回答

0

好的,我已经想出了一个答案,或者至少是一种解决方法。不觉得很优雅。事实上,我积极不喜欢它,但它的工作原理。很乐意看到更好的解决方案。在100公司server.js,首先定义父实体,像这样:

var mongoose = require('mongoose'), 
    Schema = mongoose.Schema; 

var CompanySchema = new Schema({ 
    name: { 
    type: String, 
    default: '' 
    }, 
    CEO: { 
    name: { // This is the company name, so probably a bad example 
     type: String, 
     default: '' 
    }, { 
     shoeSize: Number 
    }, etc ... 
    } 
}); 
mongoose.model('Company', CompanySchema); 

这里要注意的关键一点是,而不是把CEO的的ObjectId裁判“雇员”我提供一个使用一个对象与我的Employee模式相同的属性。根据您想要如何使用它,您可能必须将其强制转换为控制器中的Employee对象。或者,可能有一种聪明的方式来使用虚拟来做同样的事情(http://mongoosejs.com/docs/guide.html)但是,虚拟只需要在EmployeeSchema和model之后定义。

在200 employee.server.js,类似如下:

var mongoose = require('mongoose'), 
    Schema = mongoose.Schema, 
    CompanySchema = mongoose.model('Company').schema; // so you can use this 
                // after your Employee 
                // is defined 

var EmployeeSchema = new Schema({ 
    name: { 
    type: String, 
    default: '' 
    }, 
    company: { 
    type: Schema.ObjectId, 
    ref: 'Company' 
    }, 
    subordinates: [], // Just an empty array. You fill it with Employees in the controller. You could use a virtual to do the same thing, probably. 
}); 

mongoose.model('Employee', EmployeeSchema); 

因此,它是一种丑陋,但它的工作原理。

要点:

  • 在定义CompanySchema,你不使用的ObjectId裁判 '雇员'。
  • 而是定义一个看起来像公司对象的对象。
  • 由于此对象没有_id,因此您必须在 控制器中解决该问题。在我的情况下,这工作正常。但是,对于很多/大多数情况下,这个 可能不会。你必须通过巧妙的虚拟工具 和/或控制器来解决这个问题。
  • 使用一个简单的数组,没有类型来存储你的孩子(suborinates在 这个例子。 数组工作得很好,并返回就像您使用的ObjectId参考员工的数组 对象。
  • 使公司是指员工(尚未定义), 必须将一个通用对象转换为一个Employee对象。但是,有 许多方法来做到这一点。
  • 毫无疑问,有一个更好的方法要做到这一点。
相关问题