tutorial - mongodb wikipedia
Relaciones MongoDB: ¿incrustar o referencia? (10)
Si quiero editar un comentario específico, ¿cómo obtener su contenido y su pregunta?
Puede consultar 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 en la base de datos.
En general, si su documento contiene una matriz de objetos, encontrará que esos subobjetos deberán modificarse del lado del cliente.
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 hacer reference
?
Una pregunta con algunos comentarios, como Home , tendría una estructura como esta:
Question
title = ''aaa''
content = bbb''
comments = ???
Al principio, quiero usar comentarios embed
(creo que se recomienda embed
en MongoDB), como esto:
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 me permita encontrar uno, ni question_ref
que me permita encontrar su pregunta. (Soy tan novato, que no sé si hay alguna manera de hacer esto sin _id
y question_ref
).
¿Tengo que usar ref
no embed
? ¿Entonces tengo que crear una nueva colección para comentarios?
Si quiero editar un comentario específico, ¿cómo obtengo su contenido y su pregunta?
Si ha mantenido un seguimiento de la cantidad de comentarios y el índice del comentario que desea modificar, puede usar el operador de puntos ( ejemplo SO ).
Usted podría hacer f.ex.
db.questions.update(
{
"title": "aaa"
},
{
"comments.0.contents": "new text"
}
)
(como otra forma de editar los comentarios dentro de la pregunta)
Bueno, llego un poco tarde pero todavía me gustaría compartir mi forma de creación de esquemas.
Tengo esquemas para todo lo que puede ser descrito por una palabra, como lo harías en la POO clásica.
P.EJ
- Comentario
- Cuenta
- Usuario
- Entrada en el blog
- ...
Cada esquema se puede guardar como un documento o subdocumento, por lo que declaro esto para cada esquema.
Documento:
- Se puede utilizar como referencia. (Por ejemplo, el usuario hizo un comentario -> el comentario tiene una referencia "hecho por" al usuario)
- Es una "raíz" en tu aplicación. (Por ejemplo, el blogpost -> hay una página sobre el blogpost)
Subdocumento
- Solo se puede usar una vez / nunca es una referencia. (Por ejemplo, el comentario se guarda en el blogpost)
- Nunca es una "raíz" en tu aplicación. (El comentario solo aparece en la página de publicación de blog, pero la página aún trata sobre la publicación de blog)
En general, la inserción es buena si tiene relaciones de uno a uno o de uno a muchos entre entidades, y la referencia es buena si tiene relaciones de muchos a muchos.
En realidad, tengo bastante curiosidad por qué nadie habló sobre las especificaciones UML. Una regla de oro es que si tiene una agregación, entonces debería usar referencias. Pero si es una composición, entonces el acoplamiento es más fuerte y debe usar documentos incrustados.
Y rápidamente entenderás 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 no puedes incrustarlo en un padre que no existe, debes hacerlo en su propia estructura de datos. Y si existe un padre, simplemente vincúlelos agregando una referencia del objeto en el padre.
¿Realmente no sabes cuál es la diferencia entre las dos relaciones? Aquí hay un enlace explicándolos: Agregación vs Composición en UML
Eso depende del uso del documento. Cuando usa el documento, si siempre usa los comentarios, la mejor manera de usar la incrustación. Pero debes considerar el tamaño máximo del documento (16MB).
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 que debe considerar:
Poner tanto como sea posible
La alegría de una base de datos de documentos es que elimina muchas combinaciones. Su primer instinto debe ser colocar todo lo que pueda en un solo documento. Debido a que los documentos de MongoDB tienen una estructura y porque puede realizar consultas eficientes 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 mucho) 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 principal debe formar parte del mismo documento.
Datos separados 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 hacen referencia 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 4MB (16MB 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, 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 desearí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 complejos:
MongoDB puede almacenar estructuras de datos anidadas y arbitrarias, pero no puede buscarlas de manera eficiente. Si sus datos forman un árbol, bosque o gráfico, efectivamente debe 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 tener en cuenta)
También se ha señalado que es imposible devolver un subconjunto de elementos en un documento. Si necesita seleccionar y elegir algunos fragmentos de cada documento, será más fácil separarlos.
Consistencia de los datos
MongoDB hace un intercambio entre eficiencia y consistencia. La regla es que los cambios en un solo documento siempre son atómicos, mientras que las actualizaciones de múltiples documentos nunca deben asumirse como atómicas. Tampoco hay manera de "bloquear" un registro en el servidor (puede incorporarlo a la lógica del cliente utilizando, por ejemplo, un campo de "bloqueo"). Cuando diseñe su esquema, considere cómo mantendrá sus datos consistentes. En general, cuanto más se 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 ID de objeto tiene una marca de tiempo incrustada en él para que pueda usar eso en lugar de crearlo si lo desea.
Me encontré con esta pequeña presentación mientras investigaba esta pregunta por mi cuenta. Me sorprendió lo bien que estaba, tanto la información como la presentación.
http://openmymind.net/Multiple-Collections-Versus-Embedded-Documents
Se resume:
Como regla general, si tiene una gran cantidad de [documentos secundarios] o si son grandes, una colección por separado podría ser lo mejor.
Los documentos más pequeños y / o menos tienden a ser un ajuste natural para la inserción.
Sé que esto es bastante antiguo, pero si está buscando la respuesta a la pregunta del OP sobre cómo devolver solo un comentario específico, puede usar el operador $ (consulta) de la siguiente manera:
db.question.update({''comments.content'': ''xxx''}, {''comments.$'': true})
Sí, podemos usar la referencia en el documento. Para rellenar otro documento como sql i joins.In mongo db no tienen uniones para mapear uno a muchos documentos de relaciones. En lugar de eso, podemos usar populate para cumplir con nuestro escenario.
var mongoose = require(''mongoose'')
, Schema = mongoose.Schema
var personSchema = Schema({
_id : Number,
name : String,
age : Number,
stories : [{ type: Schema.Types.ObjectId, ref: ''Story'' }]
});
var storySchema = Schema({
_creator : { type: Number, ref: ''Person'' },
title : String,
fans : [{ type: Number, ref: ''Person'' }]
});
Población es el proceso de reemplazar automáticamente las rutas especificadas en el documento con documentos de otras recopilaciones. Podemos rellenar un solo documento, varios documentos, un objeto simple, varios objetos simples o todos los objetos devueltos desde una consulta. Veamos algunos ejemplos.
Mejor puede obtener más información, visite: http://mongoosejs.com/docs/populate.html