Referências no MongoDB/Mongoose

253 views
Skip to first unread message

Régis Soares

unread,
Jun 6, 2015, 8:19:33 PM6/6/15
to nod...@googlegroups.com
Pessoal,

Estou com uma dúvida sobre a melhor abordagem para tratar um problema e quero saber a opinião de vcs.

Tenho dois modelos no mongoose, um para cidade e outro para denúncia, e preciso dizer que uma denúncia se refere a uma cidade.

O conjunto de cidades tem um limite definido (são todas as cidades brasileiras), já o de denúncias tende a crescer com o tempo.

As opções que pensei são:

1) Denúncia referenciar a cidade:

var denunciaSchema = mongoose.Schema({
  cidade: { type: mongoose.Schema.Types.ObjectId, ref: 'cidade' }
  ...
});

var cidadeSchema = mongoose.Schema({ ... });
module.exports = mongoose.model('cidade', cidadeSchema);

2) Cidade ter todas as denúncias como sub documentos:

var denunciaSchema = mongoose.Schema({ ... });

var cidadeSchema = mongoose.Schema({
  denuncias: [denunciaSchema]
});

Apenas para contextualizar, falando da interface com o usuário, quando o usuário entrar na página uma cidade, serão listadas todas as denúncias daquela cidade. E uma denúncia poderá ser visualizada individualmente na página de detalhes da mesma.

Qual seria a melhor abordagem para esse problema de modelagem?

Como perguntava uma professora de estrutura de dados, na época da faculdade, quando passava um problema sinistro para os alunos resolverem: "e aí, prÓgramadores?" (o Ó é para enfatizar a forma que ela falava, pois é bahiana)

Abs,
Régis

Racz

unread,
Jun 7, 2015, 6:42:52 PM6/7/15
to nod...@googlegroups.com
Existe um limite pro tamanho de um documento no mongo, então o melhor é a primeira forma, senão quando o número de denúncias crescer, você vai estourar esse limite.
Att,
Racz

--
Você recebeu essa mensagem porque está inscrito no grupo "Node.js Brasil" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para nodebr+un...@googlegroups.com.
Para mais opções, acesse https://groups.google.com/d/optout.

Marcos Bérgamo

unread,
Jun 8, 2015, 7:27:48 AM6/8/15
to nod...@googlegroups.com
Racz ambas as abordagens podem ser validas. No caso do limite, acredito que uma vez que você use sharding esse problema seja resolvido, infelizmente não tenho tanto conhecimento do mesmo para afirmar com total certeza isso. 

Mas no seu caso não fará muita diferença, pois você conhece a cidade, então é só buscar por referencia. 

Pedro Yamada

unread,
Jun 8, 2015, 9:29:00 AM6/8/15
to nod...@googlegroups.com
Marcos, sharding não deve resolver o problema. Régis, o limite do
tamanho dos documentos nem é o problema. O problema é que você não
deve embedar um vetor de subdocumentos que pode crescer para um
tamanho arbitrário.

O motivo é que quando um documento é inserido, o MongoDB aloca espaço
no disco para o tamanho dele mais algum padding para que ele possa
crescer. Se o documento crescer além desse tamanho determinado na
inserção, o MongoDB vai ter de copiar os dados para o final da
collection no disco e isso degrada a performance de updates bastante.
Pra documentos que sejam extremamente voláteis, você pode mudar o
padding envolta do documento manualmente [1].

Em termos gerais de modelagem, a recomendação é nunca ter arrays que
possam crescer indefinidamente, só arrays que tenham um tamanho
previsível. Assim, há algum fator de padding sobre o tamanho dos
documentos que garantira que updates não movem as coisas no disco
todas as vezes.

Dependendo do seu workload, vale a pena misturar referências com
sub-documentos. Por exemplo, mantenha um vetor de tamanho limitado no
documento cidade, com os ids e informações gerais das últimas
denúncias da cidade e todas as denúncias em sua própria collection,
com mais informações. Assim, você pode buscar todas as informações
"necessárias" para mostrar uma única cidade, sem fazer dois queries.
Mas acaba tendo um modelo muito mais flexível para as denúncias.
Quando você for atualizar uma cidade e adicionar mais denúncias, você
pode atualizar esse field com as últimas denúncias usando o $slice
[2].

[1] - http://docs.mongodb.org/v2.4/core/record-padding/
[2] - http://docs.mongodb.org/manual/reference/operator/update/slice/
https://github.com/yamadapc
https://twitter.com/yamadapc
https://keybase.io/ym

Régis Soares

unread,
Jun 8, 2015, 6:30:53 PM6/8/15
to nod...@googlegroups.com
Excelente explicação, Yamada. Obrigado.

Implementei como está na primeira opção (denúncia referenciando cidade).

Uma dúvida não técnica agora: qual editor usa para redigir o email, fazendo com que ele fique com uma largura definida? Fica muito mais fácil pra ler, quando a linha do parágrafo é longa (como essa agora).

Pedro Yamada

unread,
Jun 8, 2015, 7:31:08 PM6/8/15
to nod...@googlegroups.com
Acho que o gmail em modo de texto pleno faz isso.
Estou no celular agora. Acabei de perceber que a formatação fica toda errada no Inbox. :P

Yamada
Reply all
Reply to author
Forward
0 new messages