Mongodb 如何正确地设计Mongo模式,使属于一起的元素保持在一起?

Mongodb 如何正确地设计Mongo模式,使属于一起的元素保持在一起?,mongodb,optimization,twitter,schema,Mongodb,Optimization,Twitter,Schema,作为一个粗略的例子,我有一个家族,它有许多成员,所以我使用了一个类似上面所示的模式。但一个家庭可以有数千名成员,而一名成员只能在一个家庭中。因此,每次我遇到一个新成员,我都必须搜索他是否属于任何家庭,如果他属于任何家庭,则添加他。如果他没有,我就必须建立一个新的家庭,把他加进去 这似乎是一种效率极低的做事方式。这种用例有更好的设计吗?您可以使用两个集合,一个用于族,另一个用于成员。可以使用“成员”集合中的字段将其与另一个集合的一个族(例如,通过“\u id”)链接 当您必须添加新元素时,如果元素

作为一个粗略的例子,我有一个
家族
,它有许多成员,所以我使用了一个类似上面所示的模式。但一个家庭可以有数千名成员,而一名成员只能在一个家庭中。因此,每次我遇到一个新成员,我都必须搜索他是否属于任何家庭,如果他属于任何家庭,则添加他。如果他没有,我就必须建立一个新的家庭,把他加进去


这似乎是一种效率极低的做事方式。这种用例有更好的设计吗?

您可以使用两个集合,一个用于族,另一个用于成员。可以使用“成员”集合中的字段将其与另一个集合的一个族(例如,通过“\u id”)链接


当您必须添加新元素时,如果元素已经存在,您可以在“成员”集合上搜索。索引有助于加快查询速度。

您可以使用数组对
成员的字段进行索引

或者,这里有一种非常常见的MongoDB建模技术,可以避免使用数组(这意味着您可以为给定的族成员提供更丰富的结构)。创建
族成员
。正如您所说,每个家庭成员可能只属于一个家庭,您需要在
FamilyMemberSchema
中添加一个字段,作为对
家庭的引用(使用
ref
,如下所示)

然后,可以使用查询获取特定族的所有族成员:

var FamilySchema = new Schema({
  name: String,
  indexedOn: {
    type: Date,
    default: Date.now
  },
  updatedOn: {
    type: Date,
    default: Date.now
  }
});

var FamilyMemberSchema = new Schema({
  name: String,
  family_id: { type: Schema.Types.ObjectId, ref: 'Family' }
});

// you might want an index on these fields    
FamilyMemberSchema.index({ family_id: 1, name: 1});

var Family = mongoose.Model('Family', FamilySchema);
var FamilyMember = mongoose.Model('FamilyMember', FamilyMemberSchema);

您不需要使用
ref
,因为在您的情况下使用
populate
功能不会特别有用(),但它可以更好地记录模式定义,所以我会使用它。

需要考虑的一些想法:树如何帮助您?MongoDB的一般建模实践。下面是另一个(没有层次结构那么具体):
var FamilySchema = new Schema({
  name: String,
  indexedOn: {
    type: Date,
    default: Date.now
  },
  updatedOn: {
    type: Date,
    default: Date.now
  }
});

var FamilyMemberSchema = new Schema({
  name: String,
  family_id: { type: Schema.Types.ObjectId, ref: 'Family' }
});

// you might want an index on these fields    
FamilyMemberSchema.index({ family_id: 1, name: 1});

var Family = mongoose.Model('Family', FamilySchema);
var FamilyMember = mongoose.Model('FamilyMember', FamilyMemberSchema);
FamilyMember.find().where('family_id', 'AFAMILYID').exec(/* callback */);