Mongoose 模式——对子文档使用对象而不是数组

Posted

技术标签:

【中文标题】Mongoose 模式——对子文档使用对象而不是数组【英文标题】:Mongoose schema – using an Object instead of an Array for subdocuments 【发布时间】:2014-10-24 07:34:00 【问题描述】:

我正在使用 Node(0.10.5)/Mongo(2.4)/Mongoose(3.6) 构建游戏,并且我有一个类似这样的 Mongoose 架构...

var GameStateSchema = new Schema(
    
        buildings: 
            // This object will contain buildings of the same structure, e.g.
            // "1": name: "cabin", x: 128, y: 0,
            // "2": name: "lighthouse", x: 192, y: 64
            // It'll grow to several hundred buildings.
        ,
        nextId: 3
    
);

var BuildingSchema = new Schema(
    
        name: String, x: Number, y: Number
    
);

buildings 对象中的每个建筑物使用BuildingSchema 的最佳方法是什么?我真的不想走手动验证所有内容的路线!

注意:buildings 对象不是数组,例如buildings: [BuildingSchema],因为我听说 Mongo 在大型阵列上表现不佳(而且建筑物的顺序并不重要)。

【问题讨论】:

验证所有内容是什么意思?此外,您不能在 GameStateSchema 中定义值,架构包含类型等,而不是数据。 “验证”是指检查强制转换和“模式严格模式”写入数据库。不是更复杂的 Mongoose 验证方法。天哪,是的,对不起,我忘了给数据线做评论!立即编辑。 尽管您反对,但您应该在此处使用buildings 的数组。没问题。 是的,我认为你是对的,约翰尼。我忽略了 Mongo 没有通配符字段名的事实,所以你只能通过 id 找到建筑物,例如找到所有的灯塔会很痛苦。似乎大型数组的最佳解决方案是将其拆分为较小的数组(如果它对您的数据有意义)。此外,Mongo 2.6 有 $position 修饰符,可以加快处理数组的速度。 呃,这是真的吗:搜索数组只能返回一个或所有数组元素(即不可能找到所有灯塔)?!如果是这样,数组绝对不是要走的路。下一次尝试:一个巨大的建筑碎片集合。 【参考方案1】:

啊,答案很简单。您可以使用相同的...

buildings: [BuildingSchema]

对象和数组的表示法。例如,如果您添加一个新建筑物...

GameStateSchema.update($set: "buildings.1": name: "cabin", x:128, y: 0   )

Mongoose 将使用BuildingSchema 添加一个新建筑,进行非常基本(但至关重要)的验证,例如建筑物只能有namexy

如果您在 $set 项目之前没有显式创建 buildings 数组,它将默认为对象。有点反直觉但非常方便:)

编辑——我说得太早了,结果表明通过 Mongoose 模型实例访问 buildings 只有在它是一个数组时才有效。问题仍然存在。

【讨论】:

以上是关于Mongoose 模式——对子文档使用对象而不是数组的主要内容,如果未能解决你的问题,请参考以下文章

在 Mongoose 中对子文档进行排序

使用 mongoose 对子子文档进行 CRUD

针对 Mongoose 模式验证对象而不保存为新文档

为啥有 Mongoose 模型而不仅仅是模式/文档? [复制]

用于存储子文档的 JSON 对象数组的 Mongoose 模式

Mongoose - 在保存文档之前为每个对象生成 ObjectID