database - MongoDB 在用户家庭地址上嵌入 vs 引用?

标签 database mongodb nosql

我已经阅读了一些论坛和博客文章,但在引用另一个集合时没有找到关于 MongoDB 模式结构的好的答案。

例如,如果我有一个用户集合,其中用户只属于一个地址(他的住所)。但是对于多个用户来说,一个给定的地址可能是相同的,其中地址集合结构具有以下字段:邮政编码、街道、城市、州、国家/地区。 我的问题出现在一个集合结构中,我可以有数百万用户,他们可能住在同一条街上,也可能不在同一条街上,在这种情况下,使用嵌入地址(非规范化方法)会更好在用户集合上,或使用 objectID 来引用地址集合。

最佳答案

这实际上取决于您的应用程序将如何查询数据。然而,我个人的经验法则是,如果其中有超过几百个实体/文档,则不要嵌入。您还必须记住 mongodb 中每个文档大小限制为 16mb。如果可能会创建数百万个特定类型的实体,最好将它们存储在它们自己的集合中,并从相关实体中引用指向它们。

这是一个 C# 示例,说明我将如何针对您给出的场景执行此操作:

using MongoDB.Entities;
using System.Linq;

namespace StackOverflow
{
    public class Program
    {
        public class User : Entity
        {
            public One<Address> Address { get; set; }

            public string Name { get; set; }
        }

        public class Address : Entity
        {
            public Many<User> Users { get; set; }

            public string Street { get; set; }
            public string City { get; set; }
            public string State { get; set; }
            public string ZipCode { get; set; }
            public string Country { get; set; }

            public Address() => this.InitOneToMany(() => Users);
        }

        private static void Main(string[] args)
        {
            // init connection
            new DB("test", "127.0.0.1");

            // create address
            var address = new Address
            {
                Street = "4616 Greenwood Pl",
                City = "Los Angeles",
                State = "CA",
                ZipCode = "90027",
                Country = "USA"
            }; address.Save();

            // create first user
            var user1 = new User
            {
                Name = "Amanda Woodward",
                Address = address.ToReference(),
            }; user1.Save();

            // create second user
            var user2 = new User
            {
                Name = "Billy Campbell",
                Address = address.ToReference(),
            }; user2.Save();

            // link the users to the address
            address.Users.Add(user1);
            address.Users.Add(user2);

            // find all users who live at a given address
            var result1 = DB.Queryable<User>()
                            .Where(u => u.Address.ID == address.ID)
                            .ToList();

            // find address of a given user
            var result2 = DB.Queryable<User>()
                            .Where(u => u.Name == "Amanda Woodward")
                            .Select(u => u.Address)
                            .First()
                            .ToEntity();

            // find a particular user at an address
            var result3 = address.Users.ChildrenQueryable()
                                       .Where(u => u.Name == "Billy Campbell")
                                       .First();

            // find all users living on a given street
            var addressIDs = DB.Queryable<Address>()
                               .Where(a => a.Street.Contains("Greenwood Pl"))
                               .Select(a => a.ID)
                               .ToArray();

            var result4 = DB.Queryable<User>()
                            .Where(u => addressIDs.Contains(u.Address.ID))
                            .ToList();
        }
    }
}

关于database - MongoDB 在用户家庭地址上嵌入 vs 引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58043737/

相关文章:

mysql - 如何获取每行(mysql)的单独列中所有列(数量大)的总和?

mysql - CSV 数据标准化

sql - 如何在sql server中跨服务器插入xml数据类型

mongodb - Elasticsearch River(mongodb),建模架构

java - 除了 JSON 和 XML 之外,还有其他方法从 Web 服务检索数据吗?

node.js - MongoDB 中的日期对象与 Mongoose 和 Nodejs 聚合

java - Spring mongodb @DBRef 查询在基本查询中搜索父字段

postgresql - 如何将具有 n 列的表映射到数据库?

ios - 具有组合条件的 DynamoDB 查询/扫描

javascript - 具有特定首字母缩写的两个单词的出现 MongoDB