Mongodb子文档结构最佳实践和查询

发布于 2025-01-09 04:49:52 字数 4782 浏览 0 评论 0原文

我见过两种主要类型的子文档模式:

{
    "cbill@boogiemail:com": {
        "outbound": [
            {
                "name": "First",
                "state": {
                    "saved": "[email protected]",
                    "edited": "[email protected]",
                    "status": "active"
                },
                "data": {
                }
            },
            {
                "name": "Second",
                "state": {
                    "saved": "[email protected]",
                    "edited": "[email protected]",
                    "status": "draft"
                },
                "data": {
                }
            }
        ],
        "inbound" : [
            {
                "name": "First",
                "state": {
                    "saved": "[email protected]",
                    "edited": "[email protected]",
                    "status": "active"
                },
                "data": {
                }
            },
            {
                "name": "Second",
                "state": {
                    "saved": "[email protected]",
                    "edited": "[email protected]",
                    "status": "draft"
                },
                "data": {
                }
            }
        ]
    }
}

另一种结构是:

{
    "cbill@boogiemail:com": {
        "outbound": {
            "First": {
                "state": {
                    "saved": "[email protected]",
                    "edited": "[email protected]",
                    "status": "active"
                },
                "data": {
                }
            },
            "Second": {
                "state": {
                    "saved": "[email protected]",
                    "edited": "[email protected]",
                    "status": "draft"
                },
                "data": {
                }
            }
        },
        "inbound" : {
            "First": {
                "state": {
                    "saved": "[email protected]",
                    "edited": "[email protected]",
                    "status": "active"
                },
                "data": {
                }
            },
            "Second": {
                "state": {
                    "saved": "[email protected]",
                    "edited": "[email protected]",
                    "status": "draft"
                },
                "data": {
                }
            }
        }
    }
}

两者之间的主要区别是入站/出站子文档的结构。

Mongo DB 子文档结构的最佳实践是什么? 在每种情况下,什么查询可以获得由

cbill@boogiemail:com.inbound.Second 指向的子文档?

添加更多信息:

该集合将包含许多以不同电子邮件地址开头的不同文档,但集合中的每个文档在入站/出站键下只有几个子文档。

I've seen 2 main types of schema for subdocuments:

{
    "cbill@boogiemail:com": {
        "outbound": [
            {
                "name": "First",
                "state": {
                    "saved": "[email protected]",
                    "edited": "[email protected]",
                    "status": "active"
                },
                "data": {
                }
            },
            {
                "name": "Second",
                "state": {
                    "saved": "[email protected]",
                    "edited": "[email protected]",
                    "status": "draft"
                },
                "data": {
                }
            }
        ],
        "inbound" : [
            {
                "name": "First",
                "state": {
                    "saved": "[email protected]",
                    "edited": "[email protected]",
                    "status": "active"
                },
                "data": {
                }
            },
            {
                "name": "Second",
                "state": {
                    "saved": "[email protected]",
                    "edited": "[email protected]",
                    "status": "draft"
                },
                "data": {
                }
            }
        ]
    }
}

The alternative structure is:

{
    "cbill@boogiemail:com": {
        "outbound": {
            "First": {
                "state": {
                    "saved": "[email protected]",
                    "edited": "[email protected]",
                    "status": "active"
                },
                "data": {
                }
            },
            "Second": {
                "state": {
                    "saved": "[email protected]",
                    "edited": "[email protected]",
                    "status": "draft"
                },
                "data": {
                }
            }
        },
        "inbound" : {
            "First": {
                "state": {
                    "saved": "[email protected]",
                    "edited": "[email protected]",
                    "status": "active"
                },
                "data": {
                }
            },
            "Second": {
                "state": {
                    "saved": "[email protected]",
                    "edited": "[email protected]",
                    "status": "draft"
                },
                "data": {
                }
            }
        }
    }
}

The main difference between the two is the structure of the inbound/outbound subdocuments.

What is the best practice for Mongo DB subdocument structures?
And in each case, what query would get me the subdocument pointed to by:

cbill@boogiemail:com.inbound.Second ?

To add a bit more information:

The collection will have many different documents starting with different email addresses, but each document in the collection will only have a few subdocuments under the inbound/outbound keys.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

过气美图社 2025-01-16 04:49:52

您希望以反映您打算如何使用数据的方式构建集合和文档。如果您要执行大量复杂的查询,尤其是子文档的查询,您可能会发现将文档拆分为单独的集合会更容易。一个例子是从博客文章中分割评论。

您的评论可以存储为一组子文档:

# Example post document with comment subdocuments
{
    title: 'How to Mongo!'
    content: 'So I want to talk about MongoDB.',
    comments: [
        {
            author: 'Renold',
            content: 'This post, it's amazing.'
        },
        ...
    ]
}

但是,如果您只想对评论进行复杂的查询(例如,从所有帖子中选择最新评论或获取一位作者的所有评论),这可能会导致问题。如果您计划在进行这些复杂的查询时,您最好创建两个集合:一个用于评论,另一个用于帖子。

# Example post document with "ForeignKeys" to comment documents
{
    _id: ObjectId("50c21579c5f2c80000000000"),
    title: 'How to Mongo!',
    content: 'So I want to talk about MongoDB.',
    comments: [
        ObjectId("50c21579c5f2c80000000001"),
        ObjectId("50c21579c5f2c80000000002"),
        ...
    ]
}

# Example comment document with a "ForeignKey" to a post document
{
    _id: ObjectId("50c21579c5f2c80000000001"),
    post_id: ObjectId("50c21579c5f2c80000000000"),
    title: 'Renold',
    content: 'This post, it's amazing.'
}

这类似于在关系数据库中存储“ForeignKeys”的方式。像这样标准化您的文档可以轻松查询评论和帖子。此外,由于您要分解文档,每个文档将占用更少的内存。不过,权衡是,每当任一文档发生更改时(例如,当您插入/更新/删除评论或帖子时),您都必须维护 ObjectId 引用。并且由于没有事件Mongo 中的钩子,您必须在应用程序中完成所有这些维护。

另一方面,如果您不打算对文档的子文档执行任何复杂的查询,则可能会从存储整体对象中受益。例如,您可能不会查询用户的首选项:

# Example user document with address subdocument
{
    ObjectId("50c21579c5f2c800000000421"),
    name: 'Howard',
    password: 'naughtysecret',
    address: {
        state: 'FL',
        city: 'Gainesville',
        zip: 32608
    }
}

You want to structure your collections and documents in a way that reflects how you intend to use the data. If you're going to do a lot of complex queries, especially with subdocuments, you might find it easier to split your documents up into separate collections. An example of this would be splitting comments from blog posts.

Your comments could be stored as an array of subdocuments:

# Example post document with comment subdocuments
{
    title: 'How to Mongo!'
    content: 'So I want to talk about MongoDB.',
    comments: [
        {
            author: 'Renold',
            content: 'This post, it's amazing.'
        },
        ...
    ]
}

This might cause problems, though, if you want to do complex queries on just comments (e.g. picking the most recent comments from all posts or getting all comments by one author.) If you plan on making these complex queries, you'd be better off creating two collections: one for comments and the other for posts.

# Example post document with "ForeignKeys" to comment documents
{
    _id: ObjectId("50c21579c5f2c80000000000"),
    title: 'How to Mongo!',
    content: 'So I want to talk about MongoDB.',
    comments: [
        ObjectId("50c21579c5f2c80000000001"),
        ObjectId("50c21579c5f2c80000000002"),
        ...
    ]
}

# Example comment document with a "ForeignKey" to a post document
{
    _id: ObjectId("50c21579c5f2c80000000001"),
    post_id: ObjectId("50c21579c5f2c80000000000"),
    title: 'Renold',
    content: 'This post, it's amazing.'
}

This is similar to how you'd store "ForeignKeys" in a relational database. Normalizing your documents like this makes for querying both comments and posts easy. Also, since you're breaking up your documents, each document will take up less memory. The trade-off, though, is you have to maintain the ObjectId references whenever there's a change to either document (e.g. when you insert/update/delete a comment or post.) And since there are no event hooks in Mongo, you have to do all this maintenance in your application.

On the other-hand, if you don't plan on doing any complex queries on a document's subdocuments, you might benefit from storing monolithic objects. For instance, a user's preferences isn't something you're likely to make queries for:

# Example user document with address subdocument
{
    ObjectId("50c21579c5f2c800000000421"),
    name: 'Howard',
    password: 'naughtysecret',
    address: {
        state: 'FL',
        city: 'Gainesville',
        zip: 32608
    }
}
知足的幸福 2025-01-16 04:49:52

经过一些细微的修改后,从这里找到了答案(https://www.tutorialspoint.com/how-to-select-a-specific-subdocument-in-mongodb)。

第二个示例(这是我最感兴趣的示例)的查询是:

find({ "cbill@boogiemail:com.inbound": {$exists: true}},{"cbill@boogiemail: com.inbound.Second":1}).pretty()

这会导致:

{
    "_id" : ObjectId("6216a9940b84b1a642cb925e"),
    "cbill@boogiemail:com" : {
        "inbound" : {
            "Second" : {
                "state" : {
                    "saved" : "[email protected]",
                    "edited" : "[email protected]",
                    "status" : "draft"
                },
                "data" : {
                    
                }
            }
        }
    }
}

我不确定这是否是最有效的查询 - 请随意发布任何更好的替代方案。

Found the answer from here (https://www.tutorialspoint.com/how-to-select-a-specific-subdocument-in-mongodb) after some slight modifications to that.

The query for the second example (which was the one that I was most interested in) was:

find({ "cbill@boogiemail:com.inbound": {$exists: true}},{"cbill@boogiemail:com.inbound.Second":1}).pretty()

This results in:

{
    "_id" : ObjectId("6216a9940b84b1a642cb925e"),
    "cbill@boogiemail:com" : {
        "inbound" : {
            "Second" : {
                "state" : {
                    "saved" : "[email protected]",
                    "edited" : "[email protected]",
                    "status" : "draft"
                },
                "data" : {
                    
                }
            }
        }
    }
}

Whether this is the most efficient query I'm not sure - feel free to post any better alternatives.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文