C# MongoDB文档模式

C# MongoDB文档模式,c#,mongodb,data-modeling,database,C#,Mongodb,Data Modeling,Database,我一直在从事MongoDB数据库层的web项目。我有一个特殊的实体,我不能正确地映射到文档数据库,我认为最好得到一些反馈 比如说,我有用户和项目集合。用户可以喜欢或不喜欢项目。项目中也有标签,用户也可以喜欢或不喜欢标签。我需要能够足够快地查找喜欢/不喜欢的计数 我想到的是这样的东西(对于项目): 这相当不错。但问题是,我需要知道用户是否喜欢/不喜欢标签或项目。现在,我想到的是这样的: { name: "Item Name", statistics : { like

我一直在从事MongoDB数据库层的web项目。我有一个特殊的实体,我不能正确地映射到文档数据库,我认为最好得到一些反馈

比如说,我有用户和项目集合。用户可以喜欢或不喜欢项目。项目中也有标签,用户也可以喜欢或不喜欢标签。我需要能够足够快地查找喜欢/不喜欢的计数

我想到的是这样的东西(对于项目):

这相当不错。但问题是,我需要知道用户是否喜欢/不喜欢标签或项目。现在,我想到的是这样的:

{
    name: "Item Name",
    statistics : {
        likes:      5,
        dislikes:   6
    },
    tags: [
        { 
            name: "Foo", 
            likes: 2, 
            dislikes: 1,
            votes: [
                { user: "user1_id", vote: 1 }, //like 
                { user: "user2_id", vote: 1 }, //like 
                { user: "user3_id", vote: -1 }, //dislike 
            ]
        },
        { 
            name: "Bar", 
            likes: 0,  
            dislikes: 0,
            votes: []
        }
    ]
}
这看起来很有希望,我在这里看到的最大好处是,如果有人改变主意,不喜欢他以前喜欢的东西,我可以进行原子更新

但是,我预计每个项目大约有10个标签,每个标签可能有100票。然后,我为每个项目设置了大约1000个嵌套投票对象。我知道mongodb可以处理16mb的文档,但仍然可以在一个文档中存储这么多数据吗

我应该选择标准化模型吗。可能是“tagvotes”集合和itemvotes集合?事实上,我觉得更自然

我只是在想是关系型的还是理性型的


谢谢。

在某种程度上,随着M和N的增长,在任何M x N类型的情况下,尝试嵌入所有内容都是不可能的。在达到这一点之前,您需要创建一个单独的集合并进行客户端连接;但这并不意味着你必须完全正常化一切

在这种情况下,请考虑您希望向用户显示哪些视图:显然,您希望显示该项目,它有多少喜欢和不喜欢的内容,以及应用于该项目的标记集,以及每个标记的流行程度。但是喜欢/不喜欢对象以及喜欢/不喜欢每个标记的用户的实际列表可以放入单独的文档(在单独的集合中)

使用这样的模式,您可以执行一次查询来获取项目以及需要在该项目旁边显示的所有内容。然后,如果您需要,只需再查询一次,即可获得当前用户对该项目的意见以及他们投票的与该项目相关的所有标签

在一个文档中存储这么多数据可以吗

我看不出每个对象存储的数据量有问题,但您的读取/更新模式令人担忧:每次获取项目时,您还将获取所有投票、每个用户的id等。此外,添加投票时,您将增加对象。有时候,MongoDB必须重新分配您的对象,这需要一些时间。随着时间的推移,它将了解到您正在频繁地增长对象,并且填充因子将增加,但频繁地增长对象并不是最好的主意

如果有人改变主意,不喜欢以前喜欢的东西,我可以做原子更新

这有点棘手。你可以使用
$pull
$push
,但是我不知道你怎么能让
喜欢的和不喜欢的也保持同步。此外,如果用户真的改变了主意会发生什么?您必须同时执行
$push
$pull
,如果我没有记错的话,这是不可能的

只是想知道我是在思考关系还是理性

两者都有。这是一个关系问题:-)

现在我想得出结论,你应该去规范化计数,并将这些关系存储在不同的集合中,但Hightechrider已经写过了。太慢了<代码>;-)

{
    name: "Item Name",
    statistics : {
        likes:      5,
        dislikes:   6
    },
    tags: [
        { 
            name: "Foo", 
            likes: 2, 
            dislikes: 1,
            votes: [
                { user: "user1_id", vote: 1 }, //like 
                { user: "user2_id", vote: 1 }, //like 
                { user: "user3_id", vote: -1 }, //dislike 
            ]
        },
        { 
            name: "Bar", 
            likes: 0,  
            dislikes: 0,
            votes: []
        }
    ]
}