2011-11-30 19 views
9

Vengo de un fondo de MySQL y estoy tratando de abarcar MongoDB. En particular, estoy luchando por conceptualizar cómo debo modelar las relaciones n:n de la "manera Mongo". Para este ejemplo, digamos que tenemos dos collections: users y interests. Necesitamos ser capaces de representar o la consulta para varias cosas en nuestros datos:Cómo modelar las relaciones de muchos a muchos en MongoDB (para un usuario de MySQL)

  • los intereses del usuario
  • calificación del usuario de interés, por ejemplo "Me gusta" o "no les gusta"
  • usuarios con un interés determinado
  • Contador (que puede ser incrementado/disminuido) de cada clasificación de los intereses
  • nombre de Interés

En MySQL, tendría creó una tabla users_interests indexada en ambos ID de usuario y ID de interés. Para el contador, habría tenido columnas separadas para cada tipo de calificación, y cada vez que un usuario calificaba/no calificaba un interés, realizaba una transacción para asegurarse de que los recuentos nunca fueran falsos.

He intentado reading about some schema designs, pero fue en vano.

¿Puedes ayudar a un alma perdida a encontrar el camino?

Respuesta

10

Gran pregunta. Permítanme primero esbozar un poco cómo funciona la relación N: N, luego entraré en detalles sobre cada uno de sus puntos.

N: N en MySQL normalmente tiene su tabla dinámica asociada a su usuario e intereses (tabla user_interests). En mongo haces esto de una manera un poco diferente. Aún tiene una colección de usuarios e intereses, pero en su lugar ahora, almacena una lista de claves bajo intereses para un usuario. Así que algo como esto:

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

Al almacenar sus intereses en una lista que está enchavetado fuera en su mesa de interés, se puede llevar a cabo cada una de las acciones que se requieren. Si desea hacer una consulta que se basaría en la ID que está en la tabla de intereses, haga una consulta usando el $in modifier.

Ahora para sus intereses colección que haría lo siguiente:

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

Al añadir un interés a un documento de usuarios, la variable de recuento entonces dependería de la definición de sus calificaciones. Si está almacenando sus clasificaciones en un área separada (o en lógica), entonces el valor que le asignó sería lo que relaciona luego con el valor int en interés. IE: el usuario lo califica como meh (que tiene un valor de 1) y luego agregaría 1 al valor de conteo.

Espero que esto sea útil y al menos haya aportado algunas otras ideas sobre cómo estructurarlo.

La mejor de las suertes, recuerda que MONGO ES IMPRESIONANTE.

+0

¿por qué almacenar la identificación? Es poco probable que cambie el nombre de un interés, pero conserve las referencias, ¿verdad? Además, tendrá que realizar un '$ in' para mostrar los nombres de los" me gusta ". – mnemosyn

+0

@mnemosyn Normalmente, la ruta del código tendría uno de estos dos escenarios: 1: le interesa saber qué usuarios tienen, o 2: desea ver qué intereses tiene un usuario. Con el primero, ya tiene el nombre, y ahora solo está haciendo una consulta en un ID (consulta más rápida) en lugar de una cadena. Con el segundo, tiene una lista de identificadores que nuevamente está consultando en la identificación del objeto. Además, si cambia un nombre de interés, no tiene que refactorizarlo a través de cada entrada de usuario para actualizarlo, ya que todo lo que necesita es la identificación de ese interés particular en la colección de intereses. ¡Espero que esto ayude! – Petrogad

+0

@mnemosyn ¿Qué sucede si decido aumentar el interés, desde "pescar" hasta "pescar" o algo así? – ceejayoz

1

Para mantener un recuento global de las calificaciones de cada interés, necesitará una colección separada e independiente donde actualice (agregue o resta) calificaciones utilizando operadores de actualización atómica cuando las acciones similares/desagradables para intereses las realicen los usuarios .

Puede almacenar el interés de cada usuario como una matriz de sub documentos dentro de la colección de usuarios.

La estructura JSON de estos datos sería algo similar a:

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

ya se puede consultar en las teclas internas utilizando:

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

Esto devolverá los usuarios que tienen un interés particular.

+0

De esta manera, la clasificación se desnormaliza para cada usuario, es decir, cada usuario tiene una copia de la calificación global ('calificación: 101) Esto no se puede mantener. – mnemosyn

+0

Aquí hay una diferencia entre las calificaciones y los recuentos. El recuento es global, la calificación es relativa al usuario. La calificación debe ser una cadena, sin embargo, y no un número entero. –

+0

bien, entendí mal la pregunta de OP. – mnemosyn

Cuestiones relacionadas