Eu sou novo no MongoDB - proveniente de um fundo de banco de dados relacional. Quero criar uma estrutura de perguntas com alguns comentários, mas não sei qual relacionamento usar nos comentários: embed
ou reference
?
Uma pergunta com alguns comentários, como stackoverflow , teria uma estrutura como esta:
Question
title = 'aaa'
content = bbb'
comments = ???
No começo, quero usar comentários incorporados (acho que embed
é recomendado no MongoDB), assim:
Question
title = 'aaa'
content = 'bbb'
comments = [ { content = 'xxx', createdAt = 'yyy'},
{ content = 'xxx', createdAt = 'yyy'},
{ content = 'xxx', createdAt = 'yyy'} ]
Está claro, mas estou preocupado com este caso: se eu quiser editar um comentário especificado, como obtenho o conteúdo e a pergunta? Não há _id
para me deixar encontrar um, nem question_ref
me deixar encontrar sua pergunta. (Eu sou tão novato, que não sei se há alguma maneira de fazer isso sem _id
e question_ref
.)
Eu tenho que usar ref
não embed
? Então eu tenho que criar uma nova coleção para comentários?
Respostas:
Isso é mais uma arte do que uma ciência. A documentação do Mongo sobre esquemas é uma boa referência, mas aqui estão algumas coisas a considerar:
Coloque o máximo possível
A alegria de um banco de dados de documentos é que ele elimina muitas associações. Seu primeiro instinto deve ser colocar o máximo possível em um único documento. Como os documentos do MongoDB têm estrutura e porque você pode consultar com eficiência dentro dessa estrutura (isso significa que você pode fazer parte do documento de que precisa, para que o tamanho do documento não o preocupe muito), não há necessidade imediata de normalizar dados como você faria no SQL. Em particular, qualquer dado que não seja útil além do documento pai deve fazer parte do mesmo documento.
Separe os dados que podem ser referidos de vários locais em sua própria coleção.
Esse não é um problema de "espaço de armazenamento", mas de "consistência de dados". Se muitos registros se referirem aos mesmos dados, é mais eficiente e menos propenso a erros atualizar um único registro e manter referências a ele em outros lugares.
Considerações sobre o tamanho do documento
O MongoDB impõe um limite de tamanho de 4 MB (16 MB com 1,8) em um único documento. Em um mundo de GB de dados, isso parece pequeno, mas também são 30 mil tweets ou 250 respostas típicas do Stack Overflow ou 20 fotos intermitentes. Por outro lado, isso é muito mais informações do que se pode apresentar de uma vez em uma página da Web típica. Primeiro, considere o que facilitará suas consultas. Em muitos casos, a preocupação com o tamanho do documento será otimização prematura.
Estruturas de dados complexas:
O MongoDB pode armazenar estruturas de dados aninhadas profundas arbitrárias, mas não pode pesquisá-las com eficiência. Se seus dados formarem uma árvore, floresta ou gráfico, você precisará efetivamente armazenar cada nó e suas bordas em um documento separado. (Observe que existem armazenamentos de dados projetados especificamente para esse tipo de dados que também devem ser considerados)
Também foi apontado que é impossível retornar um subconjunto de elementos em um documento. Se você precisar escolher alguns bits de cada documento, será mais fácil separá-los.
A consistência dos dados
O MongoDB faz uma troca entre eficiência e consistência. A regra é que as alterações em um único documento são sempre atômicas, enquanto as atualizações em vários documentos nunca devem ser consideradas atômicas. Também não há como "bloquear" um registro no servidor (você pode incorporar isso na lógica do cliente usando, por exemplo, um campo "lock"). Ao projetar seu esquema, considere como manterá seus dados consistentes. Geralmente, quanto mais você mantém em um documento, melhor.
Pelo que você está descrevendo, eu incorporaria os comentários e daria a cada comentário um campo de identificação com um ObjectID. O ObjectID possui um carimbo de data / hora incorporado para que você possa usá-lo em vez de criar se quiser.
fonte
Em geral, a incorporação é boa se você tiver relacionamentos um para um ou um para muitos entre entidades e a referência é boa se você tiver relacionamentos muitos para muitos.
fonte
Você pode consultar por sub-documento:
db.question.find({'comments.content' : 'xxx'})
.Isso retornará todo o documento da pergunta. Para editar o comentário especificado, você precisa encontrar o comentário no cliente, fazer a edição e salvá-lo no banco de dados.
Em geral, se seu documento contiver uma matriz de objetos, você descobrirá que esses subobjetos precisarão ser modificados no lado do cliente.
fonte
Bem, estou um pouco atrasado, mas ainda gostaria de compartilhar minha maneira de criar esquemas.
Eu tenho esquemas para tudo o que pode ser descrito por uma palavra, como você faria no POO clássico.
POR EXEMPLO
Todos os esquemas podem ser salvos como um Documento ou Subdocumento, então declaro isso para cada esquema.
Documento:
Subdocumento:
fonte
Me deparei com essa pequena apresentação enquanto pesquisava sozinha essa pergunta. Fiquei surpreso com o quão bem foi apresentado, tanto a informação quanto a apresentação.
http://openmymind.net/Multiple-Collections-Versus-Embedded-Documents
Resumiu:
fonte
a lot
? 3? 10? 100? O que élarge
? 1kb? 1MB? 3 campos? 20 campos? O que ésmaller
/fewer
?Sei que isso é bastante antigo, mas se você estiver procurando a resposta para a pergunta do OP sobre como retornar apenas comentários especificados, poderá usar o operador $ (query) como este:
fonte
Sim, nós podemos usar a referência no document.To preencher o outro documento apenas como sql i joins.In mongo db eles não têm junta-se ao mapeamento um para muitos relação document.Instead que podemos usar populate para cumprir nosso cenário ..
População é o processo de substituir automaticamente os caminhos especificados no documento por documentos de outras coleções. Podemos preencher um único documento, vários documentos, objeto simples, vários objetos simples ou todos os objetos retornados de uma consulta. Vejamos alguns exemplos.
Melhor você pode obter mais informações, visite: http://mongoosejs.com/docs/populate.html
fonte
Na verdade, estou bastante curioso por que ninguém falou sobre as especificações UML. Uma regra prática é que, se você tiver uma agregação, deverá usar referências. Mas se for uma composição, o acoplamento será mais forte e você deverá usar documentos incorporados.
E você entenderá rapidamente por que é lógico. Se um objeto puder existir independentemente do pai, será necessário acessá-lo, mesmo que o pai não exista. Como você simplesmente não pode incorporá-lo em um pai inexistente, é necessário torná-lo vivo em sua própria estrutura de dados. E se um pai existir, basta vinculá-los, adicionando uma ref do objeto no pai.
Realmente não sei qual é a diferença entre os dois relacionamentos? Aqui está um link para explicá-los: Agregação vs Composição em UML
fonte
Eu criei este quizz como referência para saber se você deve usar um ou outro
http://indie-rok.github.io/embedded-vs-reference-mongo-db
fonte
Se você acompanhou o número de comentários e o índice do comentário que deseja alterar, use o operador de ponto ( exemplo SO ).
Você poderia fazer f.ex.
(como outra maneira de editar os comentários dentro da pergunta)
fonte