具有2个(或更多)模式类型的mongoose数组

hon*_*let 5 arrays schema mongoose mongodb node.js

在这个问题的答案的基础上 ,Mongoose中的嵌套数组

我想知道是否有一种方法可以在mongoose模式中使用一个数组,该模式只接受两种类型的模式定义文档中的一种作为数组中的元素.这是什么意思?考虑定义为......的模式

var MyDocSchema = new Schema({
  name: String,
  stuff: [Stuff],
});
Run Code Online (Sandbox Code Playgroud)

把东西定义为

var Stuff = new Schema({
  name: String,
  value: Number,
});
Run Code Online (Sandbox Code Playgroud)

这有效,但如果我想要我的东西:数组能够包含Stuff或OtherStuff ....

var MyDocSchema = new Schema({
  name: String,
  stuff: [Stuff *or* OtherStuff ],
});
Run Code Online (Sandbox Code Playgroud)

其中Stuff与之前相同,OtherStuff定义为

var OtherStuff = new Schema({
  count: Number,
  when: Date,
});
Run Code Online (Sandbox Code Playgroud)

Ron*_*len 4

基本上有两种方法可以做到这一点:

  1. 将 Stuff 和 OtherStuff 存储在另一个自己的集合(同一集合)中,并仅将对象的 id 存储在字段中,然后可以填充结果。此解决方案的技巧是您要创建两个指向同一集合的猫鼬模型。

    注意:此解决方案适用于大型且差异很大的 Stuff 和 OtherStuff 对象(因为 mongoDb 存储启发式),且文档计数较低(因为填充是一个缓慢的过程)。最终,如果对象非常不同,那么它们应该有自己的领域。

  2. 使用鉴别器。基本上,您的示例需要三个文档架构(其他架构保持不变):

    // -- Stuff --
    // Please copy from above
    
    // -- OtherStuff --
    // Please copy from above
    
    // MyDocument -
    var MyDocSchema = new Schema({ name: String });
    
    // MyDocStuff - 
    var MyDocStuffSchema = new Schema({ stuff: [Stuff] });
    
    // MyDocOtherStuff - 
    var MyDocOtherStuffSchema = new Schema({ stuff: [OtherStuff] });
    
    var myDoc = new mongoose.Model( 'myDoc', myDocSchema );
    var myDocStuff = myDoc.discriminator( 'myDocStuff', myDocStuffSchema );
    var myDocOtherStuff = myDoc.discriminator( 'myDocOtherStuff', myDocOtherStuffSchema );
    
    // when writing with this method, you need to know which model is relevant
    // isOtherStuff() just checks for _when_ or _count_ fields
    if( isOtherStuff(doc) ) {
        myDocOtherStuff.create(doc);
    } else {
        myDocStuff.create(doc);
    } 
    
    Run Code Online (Sandbox Code Playgroud)

注意:这是与看起来相似的多态对象一起使用的解决方案,对于文档中的大 N 来说速度很快。