Junção um para um
Nesta página
- Introdução
- Resumo da tarefa de agregação
- Antes de começar
- Tutorial
- Adicione um estágio de correspondência para pedidos em 2020
- Adicionar um estágio de pesquisa para vincular a collection
- Adicione estágios de conjunto para criar novos campos de documento
- Adicione um estágio não definido para remover campos desnecessários
- Executar o pipeline de agregação
- Interpretar resultados
Introdução
Neste tutorial, você pode aprender como usar o PyMongo para construir um pipeline de agregação, executar a agregação em uma coleção e imprimir os resultados concluindo e executando um aplicativo de exemplo.
Essa aggregation realiza uma junção de um para um. Uma união um a um ocorre quando um documento em uma collection tem um valor de campo que corresponde a um único documento em outra collection que tem o mesmo valor de campo. A agregação corresponde a esses documentos no valor do campo e combina informações de ambas as fontes em um resultado.
Dica
Uma união de um para um não exige que os documentos tenham um relacionamento de um para um. Para saber mais sobre esse relacionamento de dados, consulte o verbete do Wikipedia sobre Um-para-um (modelo de dados).
Resumo da tarefa de agregação
Este tutorial demonstra como combinar dados de uma collection que descreve informações do produto com outra collection que descreve solicitações de clientes. Os resultados mostram uma lista de todos os pedidos feitos em 2020 que inclui os detalhes do produto associados a cada pedido.
Este exemplo utiliza duas collection:
orders
: contém documentos que descrevem pedidos individuais de produtos em uma lojaproducts
: contém documentos que descrevem os produtos que uma loja vende
Um pedido só pode conter um produto, portanto, a agregação usa uma união de um para um para corresponder um documento do pedido ao documento do produto. As collection são unidas por um campo chamado product_id
que existe em documento de ambas as collection.
Antes de começar
Antes de começar a seguir um tutorial de agregação, você deve configurar um novo aplicativo Python. Você pode usar esse aplicativo para se conectar a um sistema do MongoDB, inserir dados de amostra no MongoDB e executar o aggregation pipeline em cada tutorial.
Dica
Para saber como instalar o driver e se conectar ao MongoDB, consulte Introdução ao PyMongo
Após instalar o driver, crie um arquivo chamado agg_tutorial.py
. Cole o seguinte código neste arquivo para criar um modelo de aplicativo para os tutoriais de agregação:
from pymongo import MongoClient # Replace the placeholder with your connection string. uri = "<connection string>" client = MongoClient(uri) try: agg_db = client["agg_tutorials_db"] # Get a reference to relevant collections. # ... some_coll = # ... another_coll = # Delete any existing documents in collections. # ... some_coll.delete_many({}) # Insert sample data into the collection or collections. # ... some_data = [...] # ... some_coll.insert_many(some_data) # Create an empty pipeline array. pipeline = [] # Add code to create pipeline stages. # ... pipeline.append({...}) # Run the aggregation. # ... aggregation_result = ... # Print the aggregation results. for document in aggregation_result: print(document) finally: client.close()
Importante
No código anterior, leia os comentários de código para localizar as seções do código que você deve modificar para o tutorial que você está seguindo.
Se você tentar executar o código sem fazer alterações, encontrará um erro de conexão.
Para cada tutorial, você deve substituir o espaço reservado da connection string de conexão pela string de conexão do seu sistema. Para saber como localizar a connection string do seu sistema, consulte Criar uma connection string.
Por exemplo, se sua string de conexão for "mongodb+srv://mongodb-example:27017"
, sua atribuição de string de conexão será semelhante à seguinte:
uri = "mongodb+srv://mongodb-example:27017";
Para executar o arquivo completo após modificar o modelo de um tutorial, execute o seguinte comando em seu shell:
python3 agg_tutorial.py
Após configurar a aplicação, acesse a collection orders
e products
adicionando o seguinte código à aplicação:
orders_coll = agg_db["orders"] products_coll = agg_db["products"]
Exclua quaisquer dados existentes e insira dados de amostra na coleção orders
como mostrado no seguinte código:
orders_coll.delete_many({}) order_data = [ { "customer_id": "elise_smith@myemail.com", "orderdate": datetime(2020, 5, 30, 8, 35, 52), "product_id": "a1b2c3d4", "value": 431.43 }, { "customer_id": "tj@wheresmyemail.com", "orderdate": datetime(2019, 5, 28, 19, 13, 32), "product_id": "z9y8x7w6", "value": 5.01 }, { "customer_id": "oranieri@warmmail.com", "orderdate": datetime(2020, 1, 1, 8, 25, 37), "product_id": "ff11gg22hh33", "value": 63.13 }, { "customer_id": "jjones@tepidmail.com", "orderdate": datetime(2020, 12, 26, 8, 55, 46), "product_id": "a1b2c3d4", "value": 429.65 } ] orders_coll.insert_many(order_data)
Exclua quaisquer dados existentes e insira dados de amostra na coleção products
como mostrado no seguinte código:
products_coll.delete_many({}) product_data = [ { "id": "a1b2c3d4", "name": "Asus Laptop", "category": "ELECTRONICS", "description": "Good value laptop for students" }, { "id": "z9y8x7w6", "name": "The Day Of The Triffids", "category": "BOOKS", "description": "Classic post-apocalyptic novel" }, { "id": "ff11gg22hh33", "name": "Morphy Richardds Food Mixer", "category": "KITCHENWARE", "description": "Luxury mixer turning good cakes into great" }, { "id": "pqr678st", "name": "Karcher Hose Set", "category": "GARDEN", "description": "Hose + nosels + winder for tidy storage" } ] products_coll.insert_many(product_data)
Tutorial
Adicione um estágio de correspondência para pedidos em 2020
Adicione um estágio $match que corresponda aos pedidos feitos em 2020:
pipeline.append({ "$match": { "orderdate": { "$gte": datetime(2020, 1, 1, 0, 0, 0), "$lt": datetime(2021, 1, 1, 0, 0, 0) } } })
Adicionar um estágio de pesquisa para vincular a collection
Em seguida, adicione um estágio $lookup . O estágio $lookup
une o campo product_id
na collection orders
ao campo id
na collection products
:
pipeline.append({ "$lookup": { "from": "products", "localField": "product_id", "foreignField": "id", "as": "product_mapping" } })
Adicione estágios de conjunto para criar novos campos de documento
Em seguida, adicione dois estágios $set ao pipeline.
O primeiro estágio $set
define o campo product_mapping
como o primeiro elemento no objeto product_mapping
criado no estágio $lookup
anterior.
O segundo estágio $set
cria dois novos campos, product_name
e product_category
, a partir dos valores no campo de objeto product_mapping
:
pipeline.extend([ { "$set": { "product_mapping": {"$first": "$product_mapping"} } }, { "$set": { "product_name": "$product_mapping.name", "product_category": "$product_mapping.category" } } ])
Dica
Como esta é uma união um-para-um, o estágio $lookup
adiciona apenas um elemento de array ao documento de entrada. O pipeline usa o operador $first para recuperar os dados desse elemento.
Adicione um estágio não definido para remover campos desnecessários
Finalmente, adicione um estágio $unset . A etapa $unset
remove campos desnecessários do documento:
pipeline.append({"$unset": ["_id", "product_id", "product_mapping"]})
Interpretar resultados
O resultado agregado contém três documentos. Os documentos representam pedidos de clientes que ocorreram em 2020, com o product_name
e product_category
do produto pedido:
{ 'customer_id': 'elise_smith@myemail.com', 'orderdate': datetime.datetime(2020, 5, 30, 8, 35, 52), 'value': 431.43, 'product_name': 'Asus Laptop', 'product_category': 'ELECTRONICS' } { 'customer_id': 'oranieri@warmmail.com', 'orderdate': datetime.datetime(2020, 1, 1, 8, 25, 37), 'value': 63.13, 'product_name': 'Morphy Richardds Food Mixer', 'product_category': 'KITCHENWARE' } { 'customer_id': 'jjones@tepidmail.com', 'orderdate': datetime.datetime(2020, 12, 26, 8, 55, 46), 'value': 429.65, 'product_name': 'Asus Laptop', 'product_category': 'ELECTRONICS' }
O resultado consiste em documentos que contêm campos de documentos na collection orders
e na collection products
, unidos pela correspondência do campo product_id
presente em cada documento original.
Para visualizar o código completo deste tutorial, consulte a Aplicação de Participação Um-para- Um Concluída no Github.