Merging de Dados
O merging de dados é uma técnica fundamental para combinar informações de múltiplas fontes, criar visões unificadas e consolidar dados dispersos. O n8n oferece várias estratégias para realizar merges eficientes e precisos.
Conceitos Fundamentais
O que é Merging de Dados?
Merging é o processo de combinar dados de diferentes fontes em um resultado único, permitindo:
- Consolidação: Unir dados de múltiplas APIs
- Enriquecimento: Adicionar informações de fontes externas
- Sincronização: Manter dados atualizados entre sistemas
- Relatórios: Criar visões unificadas de informações
- Integração: Conectar sistemas diferentes
Tipos de Merge
- Concatenation: Juntar dados sequencialmente
- Join: Combinar baseado em chaves comuns
- Union: Unir datasets similares
- Intersection: Manter apenas dados comuns
- Enrichment: Adicionar dados de fontes externas
Implementação
1. Merge Node
O Merge Node é a forma mais direta de combinar dados.
Configuração básica:
{
"mode": "combine",
"combineBy": "position"
}
Configuração avançada:
{
"mode": "combine",
"combineBy": "key",
"key1": "id",
"key2": "user_id"
}
2. Code Node para Merge Customizado
Para merges complexos, use o Code Node.
// Merge simples de arrays
const dados1 = $('API 1').json;
const dados2 = $('API 2').json;
const dadosCombinados = [...dados1, ...dados2];
return dadosCombinados;
// Merge baseado em chave
const usuarios = $('API Usuarios').json;
const pedidos = $('API Pedidos').json;
const usuariosComPedidos = usuarios.map(usuario => {
const pedidosUsuario = pedidos.filter(pedido =>
pedido.user_id === usuario.id
);
return {
...usuario,
pedidos: pedidosUsuario,
total_pedidos: pedidosUsuario.length
};
});
return usuariosComPedidos;
Padrões de Merge
1. Merge por Posição
Combina dados baseado na posição nos arrays.
Implementação:
// Dados de entrada
const clientes = [
{ id: 1, nome: 'João' },
{ id: 2, nome: 'Maria' }
];
const emails = [
{ email: 'joao@exemplo.com' },
{ email: 'maria@exemplo.com' }
];
// Merge por posição
const resultado = clientes.map((cliente, index) => ({
...cliente,
email: emails[index]?.email
}));
return resultado;
2. Merge por Chave
Combina dados baseado em chaves comuns.
Implementação:
// Dados de entrada
const clientes = [
{ id: 1, nome: 'João', email: 'joao@exemplo.com' },
{ id: 2, nome: 'Maria', email: 'maria@exemplo.com' }
];
const pedidos = [
{ id: 1, cliente_id: 1, valor: 100 },
{ id: 2, cliente_id: 1, valor: 200 },
{ id: 3, cliente_id: 2, valor: 150 }
];
// Merge por chave
const clientesComPedidos = clientes.map(cliente => {
const pedidosCliente = pedidos.filter(pedido =>
pedido.cliente_id === cliente.id
);
return {
...cliente,
pedidos: pedidosCliente,
total_pedidos: pedidosCliente.length,
valor_total: pedidosCliente.reduce((sum, p) => sum + p.valor, 0)
};
});
return clientesComPedidos;
3. Merge com Enriquecimento
Adiciona dados de fontes externas.
Implementação:
// Dados base
const clientes = [
{ nome: 'João', cep: '01001-000' },
{ nome: 'Maria', cep: '20000-000' }
];
// Enriquecer com dados do ViaCEP
const clientesEnriquecidos = await Promise.all(
clientes.map(async cliente => {
try {
const response = await fetch(
`https://viacep.com.br/ws/${cliente.cep}/json/`
);
const dadosCep = await response.json();
return {
...cliente,
endereco: {
logradouro: dadosCep.logradouro,
bairro: dadosCep.bairro,
cidade: dadosCep.localidade,
uf: dadosCep.uf
}
};
} catch (error) {
return {
...cliente,
endereco: null,
erro: error.message
};
}
})
);
return clientesEnriquecidos;
Casos de Uso Práticos
1. Relatório de Vendas Consolidado
Cenário: Consolidar dados de vendas de múltiplas plataformas.
Implementação:
// Dados de diferentes fontes
const vendasEcommerce = $('E-commerce API').json;
const vendasMarketplace = $('Marketplace API').json;
const vendasLoja = $('Loja Física API').json;
// Normalizar dados
const normalizarVenda = (venda, origem) => ({
id: venda.id,
data: new Date(venda.data),
valor: parseFloat(venda.valor),
cliente: venda.cliente,
origem: origem,
produtos: venda.produtos || []
});
// Consolidar vendas
const vendasConsolidadas = [
...vendasEcommerce.map(v => normalizarVenda(v, 'ecommerce')),
...vendasMarketplace.map(v => normalizarVenda(v, 'marketplace')),
...vendasLoja.map(v => normalizarVenda(v, 'loja_fisica'))
];
// Calcular métricas
const relatorio = {
total_vendas: vendasConsolidadas.length,
valor_total: vendasConsolidadas.reduce((sum, v) => sum + v.valor, 0),
por_origem: {
ecommerce: vendasConsolidadas.filter(v => v.origem === 'ecommerce').length,
marketplace: vendasConsolidadas.filter(v => v.origem === 'marketplace').length,
loja_fisica: vendasConsolidadas.filter(v => v.origem === 'loja_fisica').length
},
vendas: vendasConsolidadas
};
return relatorio;
2. Sincronização de Clientes
Cenário: Sincronizar dados de clientes entre CRM e sistema financeiro.
Implementação:
// Dados dos sistemas
const clientesCRM = $('CRM API').json;
const clientesFinanceiro = $('Sistema Financeiro API').json;
// Função para comparar clientes
const compararClientes = (crm, financeiro) => {
const diferencas = {};
if (crm.nome !== financeiro.nome) {
diferencas.nome = { crm: crm.nome, financeiro: financeiro.nome };
}
if (crm.email !== financeiro.email) {
diferencas.email = { crm: crm.email, financeiro: financeiro.email };
}
return Object.keys(diferencas).length > 0 ? diferencas : null;
};
// Sincronizar dados
const sincronizacoes = [];
clientesCRM.forEach(clienteCRM => {
const clienteFinanceiro = clientesFinanceiro.find(
cf => cf.id === clienteCRM.id
);
if (clienteFinanceiro) {
const diferencas = compararClientes(clienteCRM, clienteFinanceiro);
if (diferencas) {
sincronizacoes.push({
cliente_id: clienteCRM.id,
diferencas,
acao: 'atualizar'
});
}
} else {
sincronizacoes.push({
cliente_id: clienteCRM.id,
dados: clienteCRM,
acao: 'criar'
});
}
});
return {
total_sincronizacoes: sincronizacoes.length,
sincronizacoes
};
3. Merge de Dados de Monitoramento
Cenário: Consolidar alertas de diferentes sistemas de monitoramento.
Implementação:
// Alertas de diferentes sistemas
const alertasSistema1 = $('Sistema 1').json;
const alertasSistema2 = $('Sistema 2').json;
const alertasSistema3 = $('Sistema 3').json;
// Consolidar alertas
const todosAlertas = [
...alertasSistema1.map(a => ({ ...a, origem: 'sistema1' })),
...alertasSistema2.map(a => ({ ...a, origem: 'sistema2' })),
...alertasSistema3.map(a => ({ ...a, origem: 'sistema3' }))
];
// Agrupar por severidade
const alertasPorSeveridade = todosAlertas.reduce((acc, alerta) => {
const severidade = alerta.severidade || 'baixa';
if (!acc[severidade]) {
acc[severidade] = [];
}
acc[severidade].push(alerta);
return acc;
}, {});
// Resumo consolidado
const resumo = {
total_alertas: todosAlertas.length,
por_severidade: {
critico: alertasPorSeveridade.critico?.length || 0,
alto: alertasPorSeveridade.alto?.length || 0,
medio: alertasPorSeveridade.medio?.length || 0,
baixo: alertasPorSeveridade.baixo?.length || 0
},
por_sistema: {
sistema1: alertasSistema1.length,
sistema2: alertasSistema2.length,
sistema3: alertasSistema3.length
},
alertas: todosAlertas
};
return resumo;
Expressões e Data Mapping
Merge Dinâmico
// Merge baseado em configuração
const configuracao = $('Config Node').json;
const dados = $json;
const resultado = configuracao.fontes.map(fonte => {
const dadosFonte = dados[fonte.nome];
return dadosFonte.map(item => ({
...item,
origem: fonte.nome,
prioridade: fonte.prioridade
}));
}).flat();
return resultado;
Merge Condicional
// Merge apenas se dados existirem
const dados1 = $('Fonte 1').json;
const dados2 = $('Fonte 2').json;
let resultado = [];
if (dados1 && dados1.length > 0) {
resultado = [...resultado, ...dados1];
}
if (dados2 && dados2.length > 0) {
resultado = [...resultado, ...dados2];
}
return resultado;
Tratamento de Erros
Merge com Tratamento de Erros
// Merge com validação de dados
const dados1 = $('Fonte 1').json;
const dados2 = $('Fonte 2').json;
const validarDados = (dados, fonte) => {
if (!Array.isArray(dados)) {
console.warn(`Dados inválidos da fonte ${fonte}`);
return [];
}
return dados;
};
const dadosValidados1 = validarDados(dados1, 'fonte1');
const dadosValidados2 = validarDados(dados2, 'fonte2');
const resultado = [...dadosValidados1, ...dadosValidados2];
return {
dados: resultado,
estatisticas: {
fonte1: dadosValidados1.length,
fonte2: dadosValidados2.length,
total: resultado.length
}
};
Merge com Fallback
// Merge com dados de fallback
const dadosPrincipais = $('Fonte Principal').json;
const dadosFallback = $('Fonte Fallback').json;
const mergeComFallback = (principal, fallback) => {
if (principal && principal.length > 0) {
return principal;
}
console.log('Usando dados de fallback');
return fallback || [];
};
const resultado = mergeComFallback(dadosPrincipais, dadosFallback);
return resultado;
Performance e Otimização
Boas Práticas
-
Otimize Consultas
- Use filtros para reduzir volume de dados
- Implemente paginação quando necessário
- Cache dados frequentemente acessados
-
Estruture Dados
- Use chaves consistentes para joins
- Normalize dados antes do merge
- Valide estrutura dos dados
-
Monitore Performance
- Acompanhe tempo de merge
- Identifique gargalos
- Use merge incremental quando possível
Exemplo de Otimização
// Merge otimizado com cache
const cacheKey = `merge_${$json.timestamp}`;
const cached = await cache.get(cacheKey);
if (cached) {
return cached;
}
// Realizar merge
const resultado = await realizarMerge($json);
// Cache resultado
await cache.set(cacheKey, resultado, 300); // 5 minutos
return resultado;
Troubleshooting
Problemas Comuns
Erro: "Dados não compatíveis"
- Verifique estrutura dos dados
- Normalize dados antes do merge
- Use validação de schema
Erro: "Performance lenta"
- Otimize consultas às fontes
- Implemente cache
- Use merge incremental
Erro: "Dados duplicados"
- Implemente deduplicação
- Use chaves únicas
- Valide dados antes do merge
Debugging
// Debug de merge
const debug = {
"dados_entrada": {
"fonte1": $('Fonte 1').json?.length || 0,
"fonte2": $('Fonte 2').json?.length || 0
},
"resultado": resultado.length,
"timestamp": $now
};
console.log('Merge Debug:', JSON.stringify(debug, null, 2));
return {
...resultado,
debug
};
Integração com Outros Nós
Fluxo Típico
Exemplo Completo
// 1. HTTP Request - Buscar clientes
{
"url": "https://api.exemplo.com/clientes",
"method": "GET"
}
// 2. HTTP Request - Buscar pedidos
{
"url": "https://api.exemplo.com/pedidos",
"method": "GET"
}
// 3. Merge Node - Combinar dados
{
"mode": "combine",
"combineBy": "key",
"key1": "id",
"key2": "cliente_id"
}
// 4. Code Node - Processar dados combinados
const dadosCombinados = $json;
const relatorio = {
total_clientes: dadosCombinados.length,
total_pedidos: dadosCombinados.reduce((sum, c) => sum + c.pedidos.length, 0),
valor_total: dadosCombinados.reduce((sum, c) =>
sum + c.pedidos.reduce((s, p) => s + p.valor, 0), 0
),
clientes: dadosCombinados
};
return relatorio;
// 5. Database - Salvar relatório
{
"operation": "insert",
"table": "relatorios",
"data": $json
}
Referências
- Merge Node - Nó específico para merge
- Data Mapping - Mapeamento avançado de dados
- Aggregate Node - Agregação de dados
- Set Node - Transformação de dados
Dica: Use merge de dados para criar visões unificadas e consolidadas de informações dispersas. Lembre-se de sempre validar e normalizar dados antes do merge para garantir consistência e qualidade.
Esta documentação está em processo de validação. Os exemplos práticos e configurações de nós apresentados precisam ser testados e validados em ambientes reais. A intenção é sempre fornecer práticas e exemplos que funcionem corretamente em produção. Se encontrar inconsistências ou problemas, por favor, reporte para que possamos melhorar a qualidade da documentação.