何时使用嵌套数组与使用单独的集合

Posted

技术标签:

【中文标题】何时使用嵌套数组与使用单独的集合【英文标题】:When to use a nested array versus using a separate collection 【发布时间】:2014-11-08 04:40:12 【问题描述】:

我需要将猫鼬与 dbref 一起使用,但我不知道哪种设计更适合我。

第一个设计:

var user = mongoose.Schema(
    name: 'string'
);

var eventSchema = mongoose.Schema(
    title: 'string',
    propietary_id: 'String',
    comments : [
        text: 'string',
        user:  type : mongoose.Schema.Types.ObjectId, ref : 'users' ,
        createdAt: type: Date, default: Date.now   
    ]
);

第二个设计:

var user = mongoose.Schema(
    name: 'string'
);

var eventSchema = mongoose.Schema(
    title: 'string',
    propietary_id: 'String'
);

var commentSchema = mongoose.Schema(
    text: 'string',
    event_id :  type : mongoose.Schema.Types.ObjectId, ref : 'events' ,
    user_id :  type : mongoose.Schema.Types.ObjectId, ref : 'users' ,
    createdAt: type: Date, default: Date.now   
);

它是如何工作的?在我的网站上有一个事件列表,如果您想查看 cmets,您必须单击每个事件,然后 angularjs 会获取所选事件的所有 cmets(文本、用户名和用户照片)。

【问题讨论】:

【参考方案1】:

这两种解决方案各有利弊,最适合您的解决方案取决于您的使用情况。请记住,您可以独立于您的设计生成完全相同的 API,这仅取决于您维护后端的速度和容易程度。首先对这两种设计的一些想法:


第一个设计:

首先评论一下,我不会将 cmets 保存为嵌套文档,而是保存为数组。否则,每个事件您只能发表一条评论。请改用此架构:

comments: [
    
        text:  type: String ,
        user:  type: mongoose.Schema.Types.ObjectId, ref : 'users' ,
        createdAt:  type: Date, default: Date.now ,
    
]

优点:

无需多个集合 您将在 get 请求中随事件返回 cmets,这意味着对您的后端的请求更少 无需将 cmets 映射到事件

缺点:

即使您不希望显示这些 cmets,您也会将这些 cmets 与活动一起返还给您 如果一个事件有很多 cmets,请求响应会很大 如果您想删除或编辑阵列中的 cmets,这将更加棘手(尽管并非不可能)

第二个设计:

优点:

您将事件和 cmets 分开,这意味着更精简的对象 您可以更轻松地提取一条评论进行编辑或删除 您可以在不使用 cmets 的情况下更轻松地获取事件,然后在其他时间点请求 cmets

缺点:

您需要始终将 cmets 映射到事件,这意味着更多代码 两个集合通常意味着两个请求 另一个集合的维护

判决:

所有优点和缺点都取决于您需要编写多少额外代码。当然,在第二种设计中,您也可以随时将 cmets 与您的事件一起返回,但是您将首先提取 cmets 并将它们与事件对象一起返回,这意味着需要维护额外的代码。

我认为第二种设计更适合您。我根据您的评论判断这一点,如果用户单击事件,您将只需要 cmets。然后,我将首先请求事件,并在用户单击事件后立即对 cme​​ts 进行另一个请求,但是,始终将 cmets 与事件一起返回应该会使 ui 更加灵活,因为 cmets 已经被加载。

最终,这一切都取决于对您来说更重要的是如何处理数据。如果您对任何一点有任何疑问,请告诉我。

【讨论】:

感谢您的回答,是否可以返回带有事件信息、2 个 cmets 和 cmets 总数的对象?在这个查询中。 Events.findOne( _id: req.params.id , function(err, obj) res.json(obj); ); 您可以为此做另一个堆栈问题并将其发送给我,因为这里的空间太小无法回答:P 但在您的 Events.findOne 回调中,您可以找到属于通风口的所有 cmets 并将它们返回在回应中。如果您想要更深入的答案,您需要编写另一个堆栈任务并将其发布在这里。 这是新问题***.com/questions/25836360/…

以上是关于何时使用嵌套数组与使用单独的集合的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB:用于搜索性能的嵌套值与单独的集合 - 数据库模式设计

第八单元 数组与集合

集合单列--Colletion

集合的嵌套(泛型)和递归算法

来自多个集合的 $lookup 和嵌套输出

可变数组(PLSQL)