Mongodb Agregation + Lookup

Asked

Viewed 68 times

2

Good evening, I need to relate two collections in mongodb, are they:

db.markets db products.

db.mercados.find()
{
  "_id": ObjectId("5bb90160995e46f1fdbf1fe8"),
  "nome_mercado": "teste",
  "localidade": "são paulo",
  "pagamentos": [
    "credito",
    "débito",
    "dinheiro",
    "vr",
    "va"
  ],
  "produtos": [
    {
      "ean": "9876",
      "preco": "2,00"
    },
    {
      "ean": "123",
      "preco": "1,99"
    }
  ],
  "data_de_atualizacao": "Sat Oct 06 2018 15:39:24 GMT-0300"
}


db.produtos.find()
{
  "_id": ObjectId("5bb78c13ec8dee50a692d18f"),
  "ean": "123",
  "nome_produto": "Corona",
  "Categoria": "Cerveja"
}
{
  "_id": ObjectId("5bb78c5fec8dee50a692d190"),
  "ean": "9876",
  "nome_produto": "passa tempo",
  "Categoria": "Bolacha"
}
{
  "_id": ObjectId("5bb78f57844b17c8cadd039c"),
  "ean": "9876",
  "nome_produto": "traquinas",
  "Categoria": "Bolacha"
}
{
  "_id": ObjectId("5bb78f9b844b17c8cadd039d"),
  "ean": "98765",
  "nome_produto": "cramecrack",
  "Categoria": "Bolacha"
}

I need something like this:

{
  "_id": ObjectId("5bb90160995e46f1fdbf1fe8"),
  "nome_mercado": "teste",
  "localidade": "são paulo",
  "pagamentos": [
    "credito",
    "débito",
    "dinheiro",
    "vr",
    "va"
  ],
  "produtos": [
    {
      "ean": "9876",
      "preco": "2,00"
      "nome_produto": "traquinas",
      "Categoria": "Bolacha"
    },
    {
      "ean": "123",
      "preco": "1,99"
      "nome_produto": "Corona",
      "Categoria": "Cerveja"

    }
  ],
  "data_de_atualizacao": "Sat Oct 06 2018 15:39:24 GMT-0300"
}

I need to link the two collections, someone can help me?

2 answers

1

Friend,

Unlike the SQL paradigm, where you relate tables and cross-reference data in the query, in Mongodb (Nosql) you will not relate the lists.

You have two possibilities here:

  1. Search the desired market in the 'markets' collection, and take the Ids (Eans) of the products to then search for each product to get the additional information you need in the application or,

  2. Create redundancy of product data in the 'market.products' list of your 'market' collection, so that you already have all the necessary data in the market consultation.

The second option will certainly scale better, is more suitable for Nosql databases.

In non-relational databases like Mongodb, worry about structuring the data at the time of recording in the collections, creating the necessary redundancies, so that in the query the data will already be ready for direct use.

0

As Eduardo Klein wrote " 'markets', and take the Ids (Eans) of products" I hope it helps.

db.mercados.aggregate([
 { $unwind: { 'path': '$produtos', 'preserveNullAndEmptyArrays': true }},
 {
        $lookup: {
            from: 'produtos',
            let: { prodean: '$produtos.ean', p:'$produtos.preco' },
            pipeline: [

                {
                    $match: {
                        $expr: {
                            $eq: ['$ean', '$$prodean' ]
                        }
                    }
                },
                {
                    $project:{
                        preco:'$$p',
                        "ean" : 1,
                        "nome_produto" : 1,
                        "Categoria" : 1
                    }
                }
            ],
            as: 'produtos'
        }
    },
    { $unwind: { 'path': '$produtos', 'preserveNullAndEmptyArrays': true }},
    {
        $group:{
            _id: '$_id',
            nome_mercado:{$first: '$nome_mercado'},
            localidade:{$first: '$localidade'},
            pagamentos:{$first: '$pagamentos'},
            produtos:{$addToSet: '$produtos'},
            data_de_atualizacao:{$first: '$data_de_atualizacao'}
        }
    }
])

Browser other questions tagged

You are not signed in. Login or sign up in order to post.