Como executo o equivalente de junção SQL no MongoDB?
Por exemplo, digamos que você tenha duas coleções (usuários e comentários) e desejo extrair todos os comentários com pid = 444, juntamente com as informações do usuário de cada uma.
comments
{ uid:12345, pid:444, comment="blah" }
{ uid:12345, pid:888, comment="asdf" }
{ uid:99999, pid:444, comment="qwer" }
users
{ uid:12345, name:"john" }
{ uid:99999, name:"mia" }
Existe uma maneira de extrair todos os comentários com um determinado campo (por exemplo, ... find ({pid: 444})) e as informações do usuário associadas a cada comentário de uma só vez?
No momento, estou recebendo primeiro os comentários que correspondem aos meus critérios e, depois, descobrindo todos os uid nesse conjunto de resultados, obtendo os objetos do usuário e os mesclando com os resultados do comentário. Parece que estou fazendo errado.
Respostas:
No Mongo 3.2, as respostas para essa pergunta não estão mais corretas. O novo operador $ lookup adicionado ao pipeline de agregação é essencialmente idêntico a uma junção externa esquerda:
https://docs.mongodb.org/master/reference/operator/aggregation/lookup/#pipe._S_lookup
Dos documentos:
É claro que o Mongo não é um banco de dados relacional, e os desenvolvedores estão tomando cuidado para recomendar casos de uso específicos para $ lookup, mas pelo menos a partir do 3.2, a junção agora é possível com o MongoDB.
fonte
Esta página no site oficial do mongodb aborda exatamente esta questão:
https://mongodb-documentation.readthedocs.io/en/latest/ecosystem/tutorial/model-data-for-ruby-on-rails.html
fonte
Podemos mesclar / juntar todos os dados em apenas uma coleção, com uma função fácil em poucas linhas, usando o console do cliente mongodb, e agora podemos realizar a consulta desejada. Abaixo um exemplo completo,
.- Autores:
.- Categorias:
.- Livros
.- Empréstimos de livros
.- A mágica:
.- Obtenha os novos dados de coleta:
.- Resposta :)
Espero que estas linhas possam ajudá-lo.
fonte
Você tem que fazer isso da maneira que você descreveu. O MongoDB é um banco de dados não relacional e não suporta junções.
fonte
Como outros já apontaram, você está tentando criar um banco de dados relacional a partir de nenhum banco de dados relacional que você realmente não queira fazer, mas de qualquer maneira, se você tiver um caso de que precisa fazer isso aqui, é uma solução que você pode usar. Primeiro, fazemos uma busca foreach na coleção A (ou no seu caso, usuários) e, em seguida, obtemos cada item como um objeto, depois usamos a propriedade object (no seu caso, uid) para pesquisar em nossa segunda coleção (nos comentários do seu caso), se podemos encontrá-lo, então temos uma correspondência e podemos imprimir ou fazer algo com ela. Espero que isso ajude você e boa sorte :)
fonte
Com a combinação certa de $ lookup , $ project e $ match , você pode associar várias tabelas em vários parâmetros. Isso ocorre porque eles podem ser encadeados várias vezes.
Suponha que desejemos fazer o seguinte ( referência )
Etapa 1: vincular todas as tabelas
você pode procurar quantas tabelas quiser.
$ lookup - um para cada tabela na consulta
$ unwind - porque os dados são desnormalizados corretamente, e outros são agrupados em matrizes
Código Python ..
Etapa 2: definir todos os condicionais
$ project : defina aqui todas as instruções condicionais, além de todas as variáveis que você deseja selecionar.
Código Python ..
Etapa 3: junte todos os condicionais
$ match - junte-se a todas as condições usando OR ou AND etc. Pode haver vários deles.
$ project : undefine todos os condicionais
Código Python ..
Praticamente qualquer combinação de tabelas, condicionais e junções pode ser feita dessa maneira.
fonte
Aqui está um exemplo de uma coleção "participar" * de atores e filmes :
https://github.com/mongodb/cookbook/blob/master/content/patterns/pivot.txt
Faz uso do
.mapReduce()
método* join - uma alternativa para ingressar em bancos de dados orientados a documentos
fonte
Você pode ingressar em duas coleções no Mongo usando a pesquisa oferecida na versão 3.2. No seu caso, a consulta seria
ou você também pode participar com relação aos usuários, haverá uma pequena alteração, conforme indicado abaixo.
Funcionará da mesma maneira que a junção esquerda e direita no SQL.
fonte
Depende do que você está tentando fazer.
Atualmente, você o configurou como um banco de dados normalizado, o que é bom, e a maneira como você o faz é apropriada.
No entanto, existem outras maneiras de fazê-lo.
Você pode ter uma coleção de postagens que incorporou comentários para cada postagem com referências aos usuários que você pode consultar iterativamente para obter. Você pode armazenar o nome do usuário com os comentários, todos eles em um documento.
O problema do NoSQL é que ele foi projetado para esquemas flexíveis e leitura e gravação muito rápidas. Em um farm típico de Big Data, o banco de dados é o maior gargalo, você tem menos mecanismos de banco de dados do que servidores de aplicativos e front-end ... eles são mais caros, mas mais poderosos, e também o espaço no disco rígido é muito barato. A normalização vem do conceito de tentar economizar espaço, mas tem um custo em fazer com que seus bancos de dados executem Junções complicadas e verifique a integridade dos relacionamentos, executando operações em cascata. Tudo isso poupa aos desenvolvedores algumas dores de cabeça se eles projetarem o banco de dados corretamente.
Com o NoSQL, se você aceitar que a redundância e o espaço de armazenamento não são problemas devido ao seu custo (tanto no tempo do processador necessário para fazer atualizações quanto nos custos do disco rígido para armazenar dados extras), a desnormalização não é um problema (para matrizes incorporadas que se tornam centenas de milhares de itens, pode ser um problema de desempenho, mas na maioria das vezes isso não é um problema). Além disso, você terá vários servidores de aplicativos e front-end para cada cluster de banco de dados. Faça com que eles façam o trabalho pesado das junções e deixem os servidores de banco de dados ficarem com leitura e gravação.
TL; DR: O que você está fazendo está bem e há outras maneiras de fazê-lo. Confira os padrões de modelo de dados da documentação do mongodb para alguns ótimos exemplos. http://docs.mongodb.org/manual/data-modeling/
fonte
Há uma especificação que muitos drivers suportam, chamada DBRef.
Retirado da documentação do MongoDB: Modelos de Dados> Referência de Modelo de Dados> Referências de Banco de Dados
fonte
$ pesquisa (agregação)
Executa uma junção externa esquerda em uma coleção não compartilhada no mesmo banco de dados para filtrar documentos da coleção "unida" para processamento. Para cada documento de entrada, o estágio de pesquisa $ adiciona um novo campo de matriz cujos elementos são os documentos correspondentes da coleção "unida". O estágio $ lookup passa esses documentos reformulados para o próximo estágio. O estágio $ lookup possui as seguintes sintaxes:
Igualdade de Correspondência
Para executar uma correspondência de igualdade entre um campo dos documentos de entrada e um campo dos documentos da coleção "unida", o estágio $ lookup possui a seguinte sintaxe:
A operação corresponderia à seguinte instrução pseudo-SQL:
URL Mongo
fonte
Antes da versão 3.2.6 , o Mongodb não suporta consulta de junção como o mysql. abaixo solução que funciona para você.
fonte
Você pode executar consultas SQL, incluindo junção no MongoDB com mongo_fdw do Postgres.
fonte
O MongoDB não permite junções, mas você pode usar plugins para lidar com isso. Verifique o plugin mongo-join. É o melhor e eu já o usei. Você pode instalá-lo usando o npm diretamente assim
npm install mongo-join
. Você pode conferir a documentação completa com exemplos .(++) ferramenta realmente útil quando precisamos ingressar em (N) coleções
(-) podemos aplicar condições apenas no nível superior da consulta
Exemplo
fonte
Você pode fazê-lo usando o pipeline de agregação, mas é difícil escrever você mesmo.
Você pode usar
mongo-join-query
para criar o pipeline de agregação automaticamente a partir da sua consulta.É assim que sua consulta seria:
Seu resultado teria o objeto de usuário no
uid
campo e você poderá vincular quantos níveis desejar. Você pode preencher a referência ao usuário, que faz referência a uma equipe, que faz referência a outra coisa, etc.Disclaimer : Eu escrevi
mongo-join-query
para resolver este problema exato.fonte
O playORM pode fazer isso por você usando S-SQL (Scalable Scalable), que apenas adiciona particionamento, de forma que você pode fazer junções dentro de partições.
fonte
Não, não parece que você está fazendo errado. As junções do MongoDB são do "lado do cliente". Praticamente como você disse:
Não é uma junção "real", mas na verdade é muito mais útil do que uma junção SQL, porque você não precisa lidar com linhas duplicadas para junções de "muitos" lados, em vez de decorar o conjunto originalmente selecionado.
Há muita bobagem e FUD nesta página. Acontece que cinco anos depois o MongoDB ainda é uma coisa.
fonte
Eu acho que, se você precisar de tabelas de dados normalizadas - precisará tentar outras soluções de banco de dados.
Mas eu encontrei essa solução para o MOngo no Git. Aliás, insere código - ele tem o nome do filme, mas o ID do filme noi .
Problema
Você tem uma coleção de atores com vários filmes que eles fizeram.
Você deseja gerar uma coleção de filmes com uma matriz de atores em cada um.
Alguns dados de amostra
Solução
Precisamos percorrer cada filme no documento do ator e emitir cada filme individualmente.
O problema aqui está na fase de redução. Não podemos emitir uma matriz da fase de redução; portanto, devemos criar uma matriz de atores dentro do documento "valor" retornado.
O códigoObserve como actor_list é realmente um objeto javascript que contém uma matriz. Observe também que o mapa emite a mesma estrutura.
Execute o seguinte para executar o mapa / reduzir, produza-o na coleção "pivô" e imprima o resultado:
printjson (db.actors.mapReduce (mapear, reduzir, "dinamizar")); db.pivot.find (). forEach (printjson);
Aqui está o exemplo de saída, observe que "Pretty Woman" e "Runaway Bride" têm "Richard Gere" e "Julia Roberts".
fonte
Podemos mesclar duas coleções usando a subconsulta mongoDB. Aqui está um exemplo, Commentss--
Userss--
Subconsulta do MongoDB para JOIN--
Obter resultado de Collection-- recém-gerado
Resultado--
Espero que isso ajude.
fonte