Como você faria uma associação muitos-para-muitos com o MongoDB?
Por exemplo; digamos que você tenha uma tabela Usuários e uma tabela Funções. Os usuários têm muitas funções, e as funções têm muitos usuários. Na área SQL, você criaria uma tabela UserRoles.
Users:
Id
Name
Roles:
Id
Name
UserRoles:
UserId
RoleId
Como o mesmo tipo de relacionamento é tratado no MongoDB?
many-to-many
associations
mongodb
Josh Close
fonte
fonte
Respostas:
Dependendo das necessidades da sua consulta, você pode colocar tudo no documento do usuário:
Para obter todos os engenheiros, use:
Se você deseja manter as funções em documentos separados, pode incluir o _id do documento na matriz de funções em vez do nome:
e configure os papéis como:
fonte
Em vez de tentar modelar de acordo com nossos anos de experiência com RDBMS, achei muito mais fácil modelar soluções de repositório de documentos usando MongoDB, Redis e outros armazenamentos de dados NoSQL otimizando para os casos de uso de leitura, considerando a capacidade atômica operações de gravação que precisam ser suportadas pelos casos de uso de gravação.
Por exemplo, os usos de um domínio "Usuários em Funções" seguem:
Isso pode ser modelado como os seguintes modelos de documento:
Para dar suporte aos usos de alta frequência, como os recursos relacionados à função da entidade Usuário, o User.Roles é intencionalmente desnormalizado, armazenado no Usuário e no Role.Users que possuem armazenamento duplicado.
Se não estiver prontamente aparente no texto, mas esse é o tipo de pensamento incentivado ao usar repositórios de documentos.
Espero que isso ajude a preencher a lacuna em relação ao lado de leitura das operações.
Para o lado da gravação, o que é incentivado é modelar de acordo com as gravações atômicas. Por exemplo, se as estruturas do documento exigirem a aquisição de um bloqueio, a atualização de um documento, o outro e, possivelmente, mais documentos, e a liberação do bloqueio, provavelmente o modelo falhou. Só porque podemos construir bloqueios distribuídos não significa que devemos usá-los.
No caso do modelo Usuário em Funções, as operações que esticam nossa prevenção de gravação atômica de bloqueios estão adicionando ou removendo um Usuário de uma Função. Nos dois casos, uma operação bem-sucedida resulta na atualização de um único usuário e um único documento de função. Se algo falhar, é fácil executar a limpeza. Essa é a única razão pela qual o padrão Unit of Work aparece bastante onde repositórios de documentos são usados.
A operação que realmente amplia nossa prevenção de gravação atômica de bloqueios está limpando uma Função, o que resultaria em muitas atualizações do Usuário para remover o Role.name da matriz User.roles. Essa operação de clear então é geralmente desencorajada, mas se necessário, pode ser implementada ordenando as operações:
No caso de um problema, que provavelmente ocorrerá na etapa 2, é fácil fazer uma reversão, pois o mesmo conjunto de nomes de usuário da etapa 1 pode ser usado para recuperar ou continuar.
fonte
Acabei de me deparar com essa pergunta e, embora seja antiga, pensei que seria útil adicionar algumas possibilidades não mencionadas nas respostas dadas. Além disso, as coisas mudaram um pouco nos últimos anos, portanto, vale ressaltar que SQL e NoSQL estão se aproximando.
Um dos comentadores levantou a sábia atitude de advertência de que "se os dados são relacionais, use relacionais". No entanto, esse comentário só faz sentido no mundo relacional, onde os esquemas sempre vêm antes do aplicativo.
MUNDO RELACIONAL: estruturar dados> Gravar aplicativo para obtê-lo
NOSQL WORLD: projetar aplicativo> estruturar dados de acordo
Mesmo que os dados sejam relacionais, o NoSQL ainda é uma opção. Por exemplo, relacionamentos um-para-muitos não são problema algum e são amplamente abordados nos documentos do MongoDB
UMA SOLUÇÃO DE 2015 PARA UM PROBLEMA DE 2010
Desde que esta pergunta foi publicada, houve sérias tentativas de aproximar o noSQL do SQL. A equipe liderada por Yannis Papakonstantinou da Universidade da Califórnia (San Diego) está trabalhando no FORWARD , uma implementação do SQL ++ que em breve poderá ser a solução para problemas persistentes, como o postado aqui.
Em um nível mais prático, o lançamento do Couchbase 4.0 significou que, pela primeira vez, você pode criar JOINs nativos no NoSQL. Eles usam seu próprio N1QL. Este é um exemplo de um
JOIN
de seus tutoriais :O N1QL permite a maioria, se não todas, as operações SQL, incluindo agregação, filtragem, etc.
A SOLUÇÃO HÍBRIDA NÃO TÃO NOVA
Se o MongoDB ainda for a única opção, gostaria de voltar ao meu argumento de que o aplicativo deve ter precedência sobre a estrutura dos dados. Nenhuma das respostas menciona a incorporação híbrida, na qual a maioria dos dados consultados é incorporada no documento / objeto e as referências são mantidas para uma minoria de casos.
Exemplo: as informações (exceto o nome da função) podem esperar? o bootstrapping do aplicativo poderia ser mais rápido se você não solicitasse nada que o usuário ainda não precisas?
Pode ser esse o caso se o usuário efetuar login e precisar ver todas as opções para todas as funções às quais ele pertence. No entanto, o usuário é um "engenheiro" e as opções para essa função raramente são usadas. Isso significa que o aplicativo precisa apenas mostrar as opções para um engenheiro, caso ele queira clicar nelas.
Isso pode ser alcançado com um documento que informa ao aplicativo no início (1) quais funções o usuário pertence e (2) onde obter informações sobre um evento vinculado a uma função específica.
Ou, melhor ainda, indexe o campo role.name na coleção de funções e talvez você não precise incorporar ObjectID () também.
Outro exemplo: as informações sobre TODAS as funções solicitadas TODAS AS VEZES?
Também pode ser que o usuário efetue login no painel e 90% do tempo execute tarefas vinculadas à função "Engenheiro". A incorporação híbrida pode ser feita para esse papel específico na íntegra e manter referências apenas para o resto.
Ser sem esquema não é apenas uma característica do NoSQL; pode ser uma vantagem nesse caso. É perfeitamente válido aninhar diferentes tipos de objetos na propriedade "Funções" de um objeto de usuário.
fonte
no caso de empregado e empresa estarem objeto de entidade, tente usar o seguinte esquema:
fonte