Group data with Sequelize and My SQL

Asked

Viewed 245 times

1

Talk young, everything jewels with you? I need a help that is the following, I want to make returns the data to groups as follows

id_categoria1: [
    {
      id: 1,
      nome: "Arquivo tramitação 1",
      arquivo_url: "arquivo1.pdf",
      id_grupos: 1,
      id_categorias: 1,
      id_projetos: 2
    }
  ],
id_categoria2: [
    {
      id: 2,
      nome: "Arquivo tramitação 2",
      arquivo_url: "arquivo2.pdf",
      id_grupos: 2,
      id_categorias: 2,
      id_projetos: 2
    },
    {
      id: 3,
      nome: "Arquivo tramitação 3",
      arquivo_url: "arquivo3.pdf",
      id_grupos: 2,
      id_categorias: 2,
      id_projetos: 2
    }
  ]

that groups the data by two columns id_categories and id_groups, wanted to know if it is possible to make this return, currently tried with group gives Sequelize documentation but it does not return the grouped values.

Current code

db.arquivos_tramitacoes.findAll({
  where: { id_projetos: id },
  group: ['id_categorias', 'id_grupos'],
}).then(data => {
  res.send(data)
})

Current Return

[
    {
        "id": 2,
        "nome": "Arquivo tramitação 2",
        "arquivo_url": "arquivo2.pdf",
        "id_grupos": 1,
        "id_categorias": 1,
        "id_projetos": 2
    },
    {
        "id": 3,
        "nome": "Arquivo tramitação 3",
        "arquivo_url": "arquivo3.pdf",
        "id_grupos": 1,
        "id_categorias": 2,
        "id_projetos": 2
    },
    {
        "id": 4,
        "nome": "Arquivo tramitação 4",
        "arquivo_url": "arquivo4.pdf",
        "id_grupos": 2,
        "id_categorias": 2,
        "id_projetos": 2
    }
]

I believe I was clear in my doubt, I thank you in advance.

1 answer

0


The behavior of group

You misunderstood how the group works. In a query group: ['tipo'] it will group the data by tipo. So if I have:

[{
    id: 1,
    nome: "A",
    tipo: 1
},
{
    id: 2,
    nome: "B",
    tipo: 2
},
{
    id: 3,
    nome: "C",
    tipo: 1
}]

He will return:


[{
    id: 1,
    nome: "A", // O id 3 foi "agrupado" aqui
    tipo: 1
},
{
    id: 2,
    nome: "B",
    tipo: 2
}]

It doesn’t make sense in your case.

Alternative

You can use a find (common Sequelize) and work upon the result in the desired way. Below is an example with reduce adapted from a response of Soen. This example groups only by one property:

const meuArray = [{
    id: 1,
    nome: "A",
    tipo: 1
  },
  {
    id: 2,
    nome: "B",
    tipo: 2
  },
  {
    id: 3,
    nome: "C",
    tipo: 1
  }
];

const groupBy = function(array, propriedade) {
  return array.reduce(function(acumulador, objAtual) {
    // Pega o valor da propriedade. Por exemplo, 'tipo' do 'id'=1 é 1.
    const grupo = objAtual[propriedade];

    // Pega o array dessa propriedade "1" se existir, senão cria um array vazio
    acumulador[grupo] = acumulador[grupo] || [];;

    // Coloca o objeto atual nesse array encontrado/criado
    acumulador[grupo].push(objAtual);

    // Retorna o acumulador pro reduce, assim ele pode ser usado na próxima "iteração"
    return acumulador;

  }, {}); // {} é o valor inicial
};

const agrupados = groupBy(meuArray, 'tipo');
const pretty = JSON.stringify(agrupados, null, 2);
document.getElementById("json").textContent = pretty;
//console.log(agrupados)
<pre id="json"></pre>


The example below I developed to group by more than one object property, but for that you need to choose an identifier for the set. Since you didn’t clarify how it would be, I chose propriedade1-propriedade2-.... Probably this algorithm is not the best solution, but it is an option.

const meuArray = [{
    id: 1,
    nome: "A",
    tipo: 1,
    caracteristica: "Muito"
  },
  {
    id: 2,
    nome: "B",
    tipo: 2,
    caracteristica: "Muito"
  },
  {
    id: 3,
    nome: "C",
    tipo: 1,
    caracteristica: "Pouco"
  },
  {
    id: 4,
    nome: "D",
    tipo: 1,
    caracteristica: "Muito"
  }
];

const groupBy = function(array, propriedades) {
  return array.reduce((acumulador, objAtual) => {
    // Aqui vamos criar o grupo
    let grupo = "";
    propriedades.forEach(prop => {
      // Concatenando os valores com -
      grupo += objAtual[prop] + "-";
    });
    // E removemos o - do final
    grupo = grupo.substring(0, grupo.length - 1);

    // Aqui continua igual
    acumulador[grupo] = acumulador[grupo] || [];;
    acumulador[grupo].push(objAtual);
    return acumulador;

  }, {}); // {} é o valor inicial
};

const agrupados = groupBy(meuArray, ['tipo', 'caracteristica']);
const pretty = JSON.stringify(agrupados, null, 2);
document.getElementById("json").textContent = pretty;
//console.log(agrupados)
<pre id="json"></pre>

  • Thanks Rafael, I believe that this solution is the best for me to apply, I tested it here and everything worked out.

Browser other questions tagged

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