Soy nuevo en MongoDB, proveniente de un fondo de base de datos relacional. Quiero diseñar una estructura de preguntas con algunos comentarios, pero no sé qué relación usar para los comentarios: ¿ embed
o reference
?
Una pregunta con algunos comentarios, como stackoverflow , tendría una estructura como esta:
Question
title = 'aaa'
content = bbb'
comments = ???
Al principio, quiero usar comentarios incrustados (creo que embed
se recomienda en MongoDB), así:
Question
title = 'aaa'
content = 'bbb'
comments = [ { content = 'xxx', createdAt = 'yyy'},
{ content = 'xxx', createdAt = 'yyy'},
{ content = 'xxx', createdAt = 'yyy'} ]
Está claro, pero me preocupa este caso: si quiero editar un comentario específico, ¿cómo obtengo su contenido y su pregunta? No hay _id
que dejarme encontrar uno, ni question_ref
dejar que encuentre su pregunta. (Soy tan novato, que no sé si hay alguna forma de hacerlo sin _id
y question_ref
).
¿Tengo que usar ref
no embed
? ¿Entonces tengo que crear una nueva colección para comentarios?
Respuestas:
Esto es más un arte que una ciencia. La documentación de Mongo sobre esquemas es una buena referencia, pero aquí hay algunas cosas a considerar:
Poner tanto como sea posible
La alegría de una base de datos de documentos es que elimina muchas uniones. Su primer instinto debe ser colocar todo lo que pueda en un solo documento. Debido a que los documentos MongoDB tienen estructura y a que puede realizar consultas de manera eficiente dentro de esa estructura (esto significa que puede tomar la parte del documento que necesita, por lo que el tamaño del documento no debería preocuparle demasiado) no hay necesidad inmediata de normalizar datos como lo harías en SQL. En particular, cualquier dato que no sea útil aparte de su documento padre debe formar parte del mismo documento.
Separe los datos a los que se puede hacer referencia desde múltiples lugares en su propia colección.
Esto no es tanto un problema de "espacio de almacenamiento" como un problema de "consistencia de datos". Si muchos registros se refieren a los mismos datos, es más eficiente y menos propenso a errores actualizar un solo registro y mantener referencias a él en otros lugares.
Consideraciones sobre el tamaño del documento
MongoDB impone un límite de tamaño de 4 MB (16 MB con 1,8) en un solo documento. En un mundo de GB de datos, esto suena pequeño, pero también son 30 mil tweets o 250 respuestas típicas de desbordamiento de pila o 20 fotos parpadeantes. Por otro lado, esta es mucha más información de la que uno podría presentar al mismo tiempo en una página web típica. Primero considere lo que facilitará sus consultas. En muchos casos, la preocupación por el tamaño de los documentos será una optimización prematura.
Estructuras de datos complejas:
MongoDB puede almacenar estructuras de datos anidadas profundas arbitrarias, pero no puede buscarlas de manera eficiente. Si sus datos forman un árbol, bosque o gráfico, efectivamente necesita almacenar cada nodo y sus bordes en un documento separado. (Tenga en cuenta que hay almacenes de datos diseñados específicamente para este tipo de datos que también se deben considerar)
También se ha señalado que es imposible devolver un subconjunto de elementos en un documento. Si necesita seleccionar algunos bits de cada documento, será más fácil separarlos.
Consistencia de los datos
MongoDB hace una compensación entre eficiencia y consistencia. La regla es que los cambios en un solo documento son siempre atómicos, mientras que las actualizaciones de varios documentos nunca deben suponerse que son atómicas. Tampoco hay forma de "bloquear" un registro en el servidor (puede construir esto en la lógica del cliente utilizando, por ejemplo, un campo "bloquear"). Cuando diseñe su esquema, considere cómo mantendrá sus datos consistentes. En general, cuanto más guarde en un documento, mejor.
Para lo que está describiendo, incrustaría los comentarios y le daría a cada comentario un campo de identificación con un ObjectID. El ObjectID tiene una marca de tiempo incrustada para que pueda usarlo en lugar de crearlo si lo desea.
fuente
En general, incrustar es bueno si tiene relaciones uno a uno o uno a muchos entre entidades, y la referencia es buena si tiene relaciones muchos a muchos.
fuente
Se pueden realizar consultas por sub-documento:
db.question.find({'comments.content' : 'xxx'})
.Esto devolverá todo el documento de la Pregunta. Para editar el comentario especificado, debe buscar el comentario en el cliente, realizar la edición y guardarlo nuevamente en la base de datos.
En general, si su documento contiene una matriz de objetos, encontrará que esos subobjetos deberán modificarse en el lado del cliente.
fuente
Bueno, llego un poco tarde pero todavía me gustaría compartir mi forma de crear esquemas.
Tengo esquemas para todo lo que se puede describir con una palabra, como lo haría en la OOP clásica.
P.EJ
Cada esquema se puede guardar como un documento o subdocumento, por lo que declaro esto para cada esquema.
Documento:
Subdocumento:
fuente
Encontré esta pequeña presentación mientras investigaba esta pregunta por mi cuenta. Me sorprendió lo bien que estaba presentada, tanto la información como la presentación de la misma.
http://openmymind.net/Multiple-Collections-Versus-Embedded-Documents
Resumió:
fuente
a lot
? 3? 10? 100? ¿Qué eslarge
? 1kb? 1MB? 3 campos? 20 campos? ¿Qué essmaller
/fewer
?Sé que esto es bastante antiguo, pero si está buscando la respuesta a la pregunta del OP sobre cómo devolver solo un comentario especificado, puede usar el operador $ (consulta) de esta manera:
fuente
Sí, podemos usar la referencia en el documento. Para rellenar el otro documento al igual que sql i une. En mongo db no tienen uniones para mapear uno a muchos documentos de relación. En lugar de eso, podemos usar rellenar para cumplir con nuestro escenario ...
La población es el proceso de reemplazar automáticamente las rutas especificadas en el documento con documentos de otras colecciones. Podemos completar un solo documento, múltiples documentos, objetos simples, múltiples objetos simples o todos los objetos devueltos por una consulta. Veamos algunos ejemplos.
Para obtener más información, visite: http://mongoosejs.com/docs/populate.html
fuente
En realidad, tengo curiosidad por qué nadie habló sobre las especificaciones UML. Una regla general es que si tiene una agregación, debe usar referencias. Pero si se trata de una composición, el acoplamiento es más fuerte y debe usar documentos incrustados.
Y comprenderá rápidamente por qué es lógico. Si un objeto puede existir independientemente del padre, entonces querrá acceder a él incluso si el padre no existe. Como simplemente no puede incrustarlo en un padre no existente, debe hacerlo vivir en su propia estructura de datos. Y si existe un elemento primario, solo vincúlelos agregando una referencia del objeto en el elemento primario.
¿Realmente no sé cuál es la diferencia entre las dos relaciones? Aquí hay un enlace que los explica: Agregación vs Composición en UML
fuente
Creé este cuestionario como referencia para saber si debe usar uno u otro
http://indie-rok.github.io/embedded-vs-reference-mongo-db
fuente
Si ha realizado un seguimiento de la cantidad de comentarios y el índice del comentario que desea modificar, puede utilizar el operador de punto ( ejemplo SO ).
Podrías hacer f.ex.
(como otra forma de editar los comentarios dentro de la pregunta)
fuente