简体   繁体   English

如何在MongoDB中建模多对多关系(对于MySQL用户)

[英]How to model many-to-many relationships in MongoDB (for a MySQL user)

I come from a MySQL background and am trying to wrap my head around MongoDB . 我来自MySQL背景,我试图围绕MongoDB In particular, I'm struggling to conceptualize how I should model n:n relationships the "Mongo way." 特别是,我正在努力构思我应该如何建模n:n关系“Mongo方式”。

For this example, let's say we have two collections : users and interests . 对于这个例子,假设我们有两个collectionsusersinterests We need to be able to represent or query for several things in our data: 我们需要能够在数据中表示或查询几件事:

  • User's interests 用户的兴趣
  • User's rating of interest, eg "like" or "dislike" 用户的兴趣评级,例如“喜欢”或“不喜欢”
  • Users with a given interest 具有特定兴趣的用户
  • Counter (which can be incremented/decremented) of each rating of the interest 每个利息评级的计数器(可递增/递减)
  • Interest name 利息名称

In MySQL , I would have created a users_interests table indexed on both user IDs and interest IDs. MySQL ,我会创建一个在用户ID 兴趣ID上编入索引的users_interests表。 For the counter, I would have had separate columns for each rating type, and each time a user rated/un-rated an interest, done a transaction to ensure that the counts were never false. 对于计数器,我会为每种评级类型设置单独的列,并且每次用户对兴趣进行评级/未评级时,都要完成一项事务以确保计数永远不会错误。

I've tried reading about some schema designs , but to no avail. 我试过阅读一些架构设计 ,但无济于事。

Can you help a lost soul find the way? 你能帮助失落的灵魂找到方向吗?

Great question. 好问题。 Let me first outline a bit of how the N:N relationship works then I'll go into detail on each of your bullet points. 让我先概述一下N:N关系的工作原理,然后我将详细介绍每个要点。

N:N in MySQL normally you have your pivot table associating between your user and interests (user_interests table). 在MySQL中N:N通常您的数据透视表与您的用户和兴趣(user_interests表)之间存在关联。 In mongo you do this a bit differently. 在mongo你这样做有点不同。 You still have a users and interest collection, however instead now, you store a list of keys under interests for a user. 您仍然拥有用户和兴趣集合,但现在,您可以存储用户感兴趣的密钥列表。 SO something like this: 这样的事情:

User Collection {
      "name":"Josh",
      "user":"jsmith",
      "interests":[
           {
            "_id":12345,
            "rating":"like"
           },
           {..}..
      ]
}

By storing your interests in a list which is keyed off on your interest table, you can perform each of the actions you require. 通过将您的兴趣存储在您感兴趣的表格中的关键列表中,您可以执行所需的每项操作。 If you wanted to do a query you'd od it based on the ID which is in the interest table then do a query using the $in modifier . 如果您想进行查询,可以根据兴趣表中的ID进行查询,然后使用$ in修饰符进行查询。

Now for your interests collection I'd do the following: 现在为了您的兴趣收集我会做以下事情:

User Interest {
      "_id":objectId
      "label":"Swimming",
      "count":intValue
}

When adding an interest to a users document, the count variable would then depend on the definition of your ratings. 当向用户文档添加兴趣时,count变量将取决于您的评级的定义。 If you're storing your ratings in a separate area (or in logic), then the value you assigned to them would be what you relate then to the int value in interest. 如果您将评级存储在单独的区域(或逻辑)中,那么您分配给它们的值将与您感兴趣的int值相关。 IE: User rates it meh (which has a value of 1) then you would add 1 to the count value. IE:用户对它进行评级(值为1)然后将计数值加1。

Hopefully this is helpful and has at the very least brought about some other ideas on how to structure it! 希望这是有用的,至少带来了一些关于如何构建它的其他想法!

Best of luck, remember MONGO IS AWESOME. 祝你好运,记住MONGO真棒。

To maintain a global count of the ratings of each interest, you will need a separate and independent collection where you update (add or subtract) ratings using atomic update operators as and when like/dislike actions for interests are performed by users. 为了维护每个兴趣的评级的全局计数,您将需要一个单独的独立集合,您可以使用原子更新运算符更新(添加或减少)评级,以及当用户执行感兴趣/不喜欢的操作时。

You can store each User's interest as an array of sub-documents within the User collection itself. 您可以将每个用户的兴趣存储为User集合本身的子文档数组。

The JSON structure of this data would be something similar to: 此数据的JSON结构类似于:

db.User
{
    name: 'joe',
    ....,
    interests : [{ name: 'swimming', rating: 10},
              { name: 'cooking', rating: 22 }
              ]
}

Now you can query on the internal keys using: 现在您可以使用以下命令查询内部键:

> db.User.find( { "interests.name" : "cooking" } )

This will return users who have a particular interest. 这将返回特别感兴趣的用户。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM