【问题标题】:MongoDB embed vs reference on users home address?MongoDB在用户家庭地址上嵌入与参考?
【发布时间】:2020-01-22 10:04:27
【问题描述】:

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

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

【问题讨论】:

    标签: database mongodb nosql


    【解决方案1】:

    这实际上取决于您的应用程序将如何查询数据。但是,我个人的经验法则是,如果其中将有超过几百个实体/文档,则不要嵌入。您还必须记住 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();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-02-09
      • 2012-05-24
      • 2011-10-13
      • 2016-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多