编辑 mongodb 中的子文档 N-N 关系

editing subdocments N-N relationship in mongodb

我有一个应用程序,其中一篇 文章 可以链接到多个 平台

文章包含平台列表,平台也包含文章列表。

有关更多详细信息,请查看我几个月前提出的这个 Whosebug 问题。

问题是如何创建文章,实现文章与平台的N-N关系

我有创建文章和删除文章设置,这样列表也会在平台中更新。

如何实现编辑文章以便更新链接到文章的平台?

为了创建和编辑链接平台,我使用了一个下拉菜单,可以在其中选择多个选项。必要的代码可以在之前链接的问题中找到。

根据您提供的信息,我会推荐两种可能的方法,从相同的基础开始:

Use two collections (articles and platforms) and store only a reference to platform documents in an array defined on article documents

如果出现以下情况,我会推荐这种方法:

  • 您的文章文档以及 平台
  • 您希望能够独立管理两个实体,同时 也在它们之间同步引用

    // articles collection schema
    {
    "_id": ...,
    "title": "I am an article",
    
    ...
    
    "platforms": [ "platform_1", "platform_2", "platform_3" ],
    ...
    }
    
    
    // platforms collection schema    
    {
    "_id": "platform_1",
    "name": "Platform 1",
    "url": "http://right/here",
    ...
    },
    
    {
    "_id": "platform_2",
    "name": "Platform 2",
    "url": "http://right/here",
    ...
    },
    
    {
    "_id": "platform_3",
    "name": "Platform 3",
    "url": "http://right/here",
    ...
    }
    

即使这种方法非常灵活,它也需要付出代价 - 如果您同时需要文章和平台数据,您将不得不向 MongoDB 实例发出更多查询,因为数据被分割成两个不同的系列。

例如,在加载文章页面时,考虑到您还想显示 platforms 的列表,则必须向 articles collection 触发查询,然后再触发一个在 platforms collection 上搜索以检索通过 article document.

上的 platforms 数组成员发布该文章的所有平台实体

但是,如果您只有一小部分经常访问的 platform attributes 需要在加载 article document 时可用,您可以增强 platforms 数组 articles collection 除了 _id 对平台文档的引用之外,还存储这些属性:

// enhanced articles collection schema  
{
"_id": ...,
"title": "I am an article",

...

"platforms": [
    {platform_id: "platform_1", name: "Platform 1"},
    {platform_id: "platform_2", name: "Platform 2"},
    {platform_id: "platform_3", name: "Platform 3"}
],

...

}

如果您经常检索与文章特定数据一起显示的 platform data attributes 不经常更改,那么这种混合方法将是合适的。

否则,您必须将对 platforms collection 中的 platform document attributes 所做的所有更新与您作为文章文档平台数组的一部分跟踪的属性子集同步。

关于个别平台文章列表的管理,我不建议在两个集合中都存储N对N的引用,因为上述机制已经允许您通过查询articles collection来提取文章列表使用 _id 值为 platform document:

的查找查询
Approach #1
db.articles.find({"platforms": "platform_1"});

Approach #2:
db.articles.find({"platforms.platform_id": "platform_1"});

介绍了两种不同的方法后,我现在建议您分析应用程序的查询模式和性能阈值,并根据您遇到的场景做出计算决策。