Pular para conteúdo

MONGODB FIND_ONE_AND_REPLACE - Buscar e Substituir Documento Completo

O que é este Node?

O MONGODB FIND_ONE_AND_REPLACE é o node responsável por buscar um documento e substituí-lo completamente por um novo documento em uma única operação atômica.

Por que este Node existe?

Às vezes você precisa substituir um documento inteiro, não apenas atualizar campos. O MONGODB FIND_ONE_AND_REPLACE existe para:

  1. Substituição completa: Trocar documento inteiro mantendo apenas o _id
  2. Operação atômica: Buscar e substituir de forma segura sem race conditions
  3. Retornar documento: Ver o documento substituído imediatamente
  4. Upsert: Criar documento se não existir (insert + replace em uma operação)

Como funciona internamente?

Quando o MONGODB FIND_ONE_AND_REPLACE é executado, o sistema:

  1. Valida configuração: Verifica se as credenciais MongoDB foram fornecidas
  2. Estabelece conexão: Conecta ao servidor MongoDB usando as credenciais
  3. Seleciona coleção: Acessa a coleção especificada no banco de dados
  4. Processa query e document: Substitui variáveis em ambos os objetos
  5. Converte _id: Transforma strings de ObjectId quando necessário
  6. Executa findOneAndReplace: Busca e substitui em uma operação atômica
  7. Mantém _id: O _id do documento original é preservado
  8. Suporta upsert: Se upsert:true e não encontrar, cria novo documento
  9. Retorna documento novo: Usa returnDocument:'after'
  10. Fecha conexão: Encerra a conexão com MongoDB

DIFERENÇA de UPDATE: Replace substitui TODO o documento, Update modifica apenas campos específicos.

Código interno (mongodb.executor.ts:250-273):

private async findOneAndReplace(
  db: Db,
  collectionName: string,
  query: any,
  document: any,
  options: any,
  context: ExecutionContext,
): Promise<any> {
  const replacedQuery = this.replaceObjectVariables(query, context.variables);
  const replacedDocument = this.replaceObjectVariables(document, context.variables);
  const parsedQuery = this.parseMongoQuery(replacedQuery);

  const collection = db.collection(collectionName);
  const result = await collection.findOneAndReplace(
    parsedQuery,
    replacedDocument,
    {
      upsert: options.upsert || false,
      returnDocument: 'after',
    },
  );

  return result.value;
}

Quando você DEVE usar este Node?

Use MONGODB FIND_ONE_AND_REPLACE sempre que precisar substituir documento completo:

Casos de uso

  1. Reescrever configuração: "Substituir todas as configurações de uma vez"
  2. Atualizar estrutura: "Trocar documento com estrutura antiga por nova"
  3. Reset completo: "Resetar documento mantendo apenas o ID"
  4. Migração de schema: "Substituir documento com nova estrutura"

Quando NÃO usar MONGODB FIND_ONE_AND_REPLACE

  • Atualizar alguns campos: Use MONGODB FIND_ONE_AND_UPDATE (mais eficiente)
  • Múltiplos documentos: Não há replaceMany, use loops ou UPDATE
  • Apenas buscar: Use MONGODB FIND_ONE sem modificar
  • Preservar campos: Use UPDATE se quiser manter alguns campos

Parâmetros Detalhados

operation (string, obrigatório)

O que é: Define qual operação MongoDB será executada. Para buscar e substituir, use "findOneAndReplace".

Padrão: Nenhum (obrigatório)

Flow completo para testar:

{
  "name": "Teste MongoDB FindOneAndReplace - Operation",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "mongodb_1",
      "type": "mongodb",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Substituir Config",
        "operation": "findOneAndReplace",
        "config": {
          "connectionString": "mongodb://localhost:27017",
          "database": "app"
        },
        "collection": "configuracoes",
        "query": { "chave": "email" },
        "document": {
          "chave": "email",
          "smtp": {
            "host": "smtp.gmail.com",
            "port": 587,
            "secure": true
          },
          "remetente": "noreply@example.com"
        },
        "responseVariable": "novaConfig"
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "✅ Config {{novaConfig.chave}} substituída"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 700, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "mongodb_1" },
    { "source": "mongodb_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: 1. Execute o flow 2. Espere: "✅ Config email substituída"

config (object, obrigatório)

O que é: Objeto contendo as credenciais e configurações de conexão com o MongoDB.

Estrutura: - connectionString (string): String de conexão completa MongoDB - OU host, port, user, password: Configuração individual - database (string, obrigatório): Nome do banco de dados

Flow completo para testar:

{
  "name": "Teste MongoDB FindOneAndReplace - Config",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "mongodb_1",
      "type": "mongodb",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Replace com Auth",
        "operation": "findOneAndReplace",
        "config": {
          "host": "localhost",
          "port": 27017,
          "database": "app",
          "user": "admin",
          "password": "senha123"
        },
        "collection": "settings",
        "query": { "nome": "geral" },
        "document": {
          "nome": "geral",
          "tema": "escuro",
          "idioma": "pt-BR"
        },
        "responseVariable": "settings"
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "Settings atualizados: {{settings.tema}}"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 700, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "mongodb_1" },
    { "source": "mongodb_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: 1. Configure MongoDB com autenticação 2. Execute o flow 3. Espere: "Settings atualizados: escuro"

collection (string, obrigatório)

O que é: Nome da coleção MongoDB onde o documento será buscado e substituído.

Flow completo para testar:

{
  "name": "Teste MongoDB FindOneAndReplace - Collection",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "mongodb_1",
      "type": "mongodb",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Substituir na Coleção",
        "operation": "findOneAndReplace",
        "config": {
          "connectionString": "mongodb://localhost:27017",
          "database": "crm"
        },
        "collection": "perfis",
        "query": { "usuario": "joao" },
        "document": {
          "usuario": "joao",
          "nome": "João Silva",
          "email": "joao@example.com",
          "preferencias": {
            "notificacoes": true,
            "newsletter": false
          }
        },
        "responseVariable": "perfil"
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Mostrar Perfil",
        "parameters": {
          "message": "Perfil de {{perfil.nome}} atualizado"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 700, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "mongodb_1" },
    { "source": "mongodb_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: 1. Execute o flow 2. Espere: "Perfil de João Silva atualizado"

query (object, obrigatório)

O que é: Filtro para encontrar o documento a ser substituído. Apenas o primeiro documento encontrado será substituído.

Flow completo para testar:

{
  "name": "Teste MongoDB FindOneAndReplace - Query",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "mongodb_1",
      "type": "mongodb",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Buscar e Substituir",
        "operation": "findOneAndReplace",
        "config": {
          "connectionString": "mongodb://localhost:27017",
          "database": "blog"
        },
        "collection": "posts",
        "query": {
          "slug": "primeiro-post",
          "rascunho": true
        },
        "document": {
          "slug": "primeiro-post",
          "titulo": "Meu Primeiro Post Publicado",
          "conteudo": "Conteúdo completo do post...",
          "autor": "João Silva",
          "tags": ["novidade", "anuncio"],
          "rascunho": false,
          "dataPublicacao": "{{now}}"
        },
        "responseVariable": "post"
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "✅ Post publicado: {{post.titulo}}"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 700, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "mongodb_1" },
    { "source": "mongodb_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: 1. Execute o flow 2. Espere: "✅ Post publicado: Meu Primeiro Post Publicado"

document (object, obrigatório)

O que é: Novo documento que substituirá completamente o documento encontrado. Apenas o _id será preservado.

IMPORTANTE: Todos os campos do documento antigo serão removidos, exceto _id.

Flow completo para testar:

{
  "name": "Teste MongoDB FindOneAndReplace - Document",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "mongodb_1",
      "type": "mongodb",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Substituir Documento",
        "operation": "findOneAndReplace",
        "config": {
          "connectionString": "mongodb://localhost:27017",
          "database": "app"
        },
        "collection": "cache",
        "query": { "chave": "sessao_usuario_123" },
        "document": {
          "chave": "sessao_usuario_123",
          "dados": {
            "userId": "123",
            "nome": "João Silva",
            "email": "joao@example.com"
          },
          "expiraEm": "{{date_add_hours(now, 2)}}",
          "criadoEm": "{{now}}"
        },
        "responseVariable": "cache"
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "✅ Cache atualizado para {{cache.dados.nome}}"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 700, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "mongodb_1" },
    { "source": "mongodb_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: 1. Execute o flow 2. Espere: "✅ Cache atualizado para João Silva"

upsert (boolean, opcional)

O que é: Se true, cria um novo documento se nenhum for encontrado (INSERT + REPLACE).

Padrão: false

Flow completo para testar:

{
  "name": "Teste MongoDB FindOneAndReplace - Upsert",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "mongodb_1",
      "type": "mongodb",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Upsert Configuração",
        "operation": "findOneAndReplace",
        "config": {
          "connectionString": "mongodb://localhost:27017",
          "database": "app"
        },
        "collection": "configuracoes",
        "query": { "modulo": "notificacoes" },
        "document": {
          "modulo": "notificacoes",
          "email": {
            "ativo": true,
            "smtp": "smtp.gmail.com"
          },
          "push": {
            "ativo": false
          },
          "dataAtualizacao": "{{now}}"
        },
        "upsert": true,
        "responseVariable": "config"
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "✅ Config {{config.modulo}} salva"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 700, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "mongodb_1" },
    { "source": "mongodb_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: 1. Execute o flow (mesmo se módulo não existir) 2. Espere: "✅ Config notificacoes salva"

responseVariable (string, opcional)

O que é: Nome da variável onde o documento substituído será armazenado.

Padrão: Se não especificado, resultado não é armazenado

Flow completo para testar:

{
  "name": "Teste MongoDB FindOneAndReplace - Response Variable",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "mongodb_1",
      "type": "mongodb",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Salvar Resultado",
        "operation": "findOneAndReplace",
        "config": {
          "connectionString": "mongodb://localhost:27017",
          "database": "loja"
        },
        "collection": "produtos",
        "query": { "_id": "507f1f77bcf86cd799439011" },
        "document": {
          "nome": "Notebook Dell Novo",
          "preco": 3299.90,
          "estoque": 20,
          "especificacoes": {
            "processador": "Intel i7",
            "memoria": "16GB",
            "ssd": "512GB"
          },
          "dataAtualizacao": "{{now}}"
        },
        "responseVariable": "produtoNovo"
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Usar Variável",
        "parameters": {
          "message": "✅ Produto substituído!\n\n📦 Nome: {{produtoNovo.nome}}\n💰 Preço: R$ {{produtoNovo.preco}}\n📊 Estoque: {{produtoNovo.estoque}}"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 700, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "mongodb_1" },
    { "source": "mongodb_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: 1. Execute o flow 2. Espere: "✅ Produto substituído! 📦 Nome: Notebook Dell Novo ..."

Parâmetros

Campo Tipo Obrigatório Descrição
operation string Sim Tipo de operação MongoDB ("findOneAndReplace")
config object Sim Configuração de conexão MongoDB
collection string Sim Nome da coleção
query object Sim Filtro para encontrar documento
document object Sim Novo documento que substituirá o antigo
upsert boolean Não Criar se não existir (padrão: false)
responseVariable string Não Variável para armazenar documento

Exemplo 1: Reset de Configurações

Objetivo: Substituir configurações antigas por novas padrão

JSON para Importar

{
  "name": "Reset de Configurações",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "input_usuario",
      "type": "input",
      "position": { "x": 250, "y": 100 },
      "data": {
        "label": "Usuário",
        "parameters": {
          "message": "Digite o ID do usuário para resetar configurações:",
          "variable": "userId"
        }
      }
    },
    {
      "id": "message_warning",
      "type": "message",
      "position": { "x": 400, "y": 100 },
      "data": {
        "label": "Aviso",
        "parameters": {
          "message": "⚠️ Isso irá RESETAR todas as configurações para o padrão.\n\nDigite 'CONFIRMAR' para continuar:"
        }
      }
    },
    {
      "id": "input_confirm",
      "type": "input",
      "position": { "x": 550, "y": 100 },
      "data": {
        "label": "Confirmação",
        "parameters": {
          "variable": "confirmacao"
        }
      }
    },
    {
      "id": "condition_1",
      "type": "condition",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Confirmou?",
        "conditions": [
          {
            "variable": "confirmacao",
            "operator": "equals",
            "value": "CONFIRMAR",
            "targetNode": "mongodb_replace"
          }
        ],
        "defaultTarget": "message_cancelled"
      }
    },
    {
      "id": "mongodb_replace",
      "type": "mongodb",
      "position": { "x": 850, "y": 50 },
      "data": {
        "label": "Reset Config",
        "operation": "findOneAndReplace",
        "config": {
          "connectionString": "mongodb://localhost:27017",
          "database": "app"
        },
        "collection": "configuracoes_usuario",
        "query": {
          "userId": "{{userId}}"
        },
        "document": {
          "userId": "{{userId}}",
          "tema": "claro",
          "idioma": "pt-BR",
          "notificacoes": {
            "email": true,
            "push": true,
            "sms": false
          },
          "privacidade": {
            "perfilPublico": false,
            "mostrarEmail": false
          },
          "dataReset": "{{now}}"
        },
        "upsert": true,
        "responseVariable": "configReset"
      }
    },
    {
      "id": "message_success",
      "type": "message",
      "position": { "x": 1000, "y": 50 },
      "data": {
        "label": "Sucesso",
        "parameters": {
          "message": "✅ Configurações resetadas!\n\n👤 Usuário: {{configReset.userId}}\n🎨 Tema: {{configReset.tema}}\n🌍 Idioma: {{configReset.idioma}}"
        }
      }
    },
    {
      "id": "message_cancelled",
      "type": "message",
      "position": { "x": 850, "y": 150 },
      "data": {
        "label": "Cancelado",
        "parameters": {
          "message": "❌ Reset cancelado"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1150, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "input_usuario" },
    { "source": "input_usuario", "target": "message_warning" },
    { "source": "message_warning", "target": "input_confirm" },
    { "source": "input_confirm", "target": "condition_1" },
    { "source": "mongodb_replace", "target": "message_success" },
    { "source": "message_success", "target": "end_1" },
    { "source": "message_cancelled", "target": "end_1" }
  ]
}

Saída esperada:

Sistema: Digite o ID do usuário para resetar configurações:
Usuário: user-123
Sistema: ⚠️ Isso irá RESETAR todas as configurações para o padrão.

Digite 'CONFIRMAR' para continuar:
Usuário: CONFIRMAR
Sistema: ✅ Configurações resetadas!

👤 Usuário: user-123
🎨 Tema: claro
🌍 Idioma: pt-BR

Exemplo 2: Publicar Rascunho de Post

Objetivo: Substituir rascunho por versão publicada completa

JSON para Importar

{
  "name": "Publicar Rascunho de Post",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "input_slug",
      "type": "input",
      "position": { "x": 250, "y": 100 },
      "data": {
        "label": "Slug do Post",
        "parameters": {
          "message": "Digite o slug do post para publicar:",
          "variable": "slug"
        }
      }
    },
    {
      "id": "mongodb_find",
      "type": "mongodb",
      "position": { "x": 400, "y": 100 },
      "data": {
        "label": "Buscar Rascunho",
        "operation": "findOne",
        "config": {
          "connectionString": "mongodb://localhost:27017",
          "database": "blog"
        },
        "collection": "posts",
        "query": {
          "slug": "{{slug}}",
          "rascunho": true
        },
        "responseVariable": "rascunho"
      }
    },
    {
      "id": "condition_1",
      "type": "condition",
      "position": { "x": 550, "y": 100 },
      "data": {
        "label": "Encontrou?",
        "conditions": [
          {
            "variable": "rascunho",
            "operator": "not_equals",
            "value": "null",
            "targetNode": "mongodb_replace"
          }
        ],
        "defaultTarget": "message_not_found"
      }
    },
    {
      "id": "mongodb_replace",
      "type": "mongodb",
      "position": { "x": 700, "y": 50 },
      "data": {
        "label": "Publicar Post",
        "operation": "findOneAndReplace",
        "config": {
          "connectionString": "mongodb://localhost:27017",
          "database": "blog"
        },
        "collection": "posts",
        "query": {
          "slug": "{{slug}}"
        },
        "document": {
          "slug": "{{slug}}",
          "titulo": "{{rascunho.titulo}}",
          "conteudo": "{{rascunho.conteudo}}",
          "autor": "{{rascunho.autor}}",
          "tags": "{{rascunho.tags}}",
          "rascunho": false,
          "publicado": true,
          "dataPublicacao": "{{now}}",
          "visualizacoes": 0
        },
        "responseVariable": "postPublicado"
      }
    },
    {
      "id": "message_success",
      "type": "message",
      "position": { "x": 850, "y": 50 },
      "data": {
        "label": "Publicado",
        "parameters": {
          "message": "✅ Post publicado!\n\n📝 Título: {{postPublicado.titulo}}\n✍️ Autor: {{postPublicado.autor}}\n📅 Data: {{postPublicado.dataPublicacao}}"
        }
      }
    },
    {
      "id": "message_not_found",
      "type": "message",
      "position": { "x": 700, "y": 150 },
      "data": {
        "label": "Não Encontrado",
        "parameters": {
          "message": "❌ Rascunho não encontrado"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1000, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "input_slug" },
    { "source": "input_slug", "target": "mongodb_find" },
    { "source": "mongodb_find", "target": "condition_1" },
    { "source": "mongodb_replace", "target": "message_success" },
    { "source": "message_success", "target": "end_1" },
    { "source": "message_not_found", "target": "end_1" }
  ]
}

Saída esperada:

Sistema: Digite o slug do post para publicar:
Usuário: meu-primeiro-post
Sistema: ✅ Post publicado!

📝 Título: Meu Primeiro Post
✍️ Autor: João Silva
📅 Data: 2024-01-15T14:30:00.000Z

Exemplo 3: Migração de Schema

Objetivo: Substituir documento com schema antigo por novo schema

JSON para Importar

{
  "name": "Migração de Schema de Cliente",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "mongodb_find_old",
      "type": "mongodb",
      "position": { "x": 250, "y": 100 },
      "data": {
        "label": "Buscar Schema Antigo",
        "operation": "findOne",
        "config": {
          "connectionString": "mongodb://localhost:27017",
          "database": "crm"
        },
        "collection": "clientes",
        "query": {
          "schemaVersion": { "$exists": false }
        },
        "responseVariable": "clienteAntigo"
      }
    },
    {
      "id": "condition_1",
      "type": "condition",
      "position": { "x": 400, "y": 100 },
      "data": {
        "label": "Tem Cliente para Migrar?",
        "conditions": [
          {
            "variable": "clienteAntigo",
            "operator": "not_equals",
            "value": "null",
            "targetNode": "mongodb_replace"
          }
        ],
        "defaultTarget": "message_done"
      }
    },
    {
      "id": "mongodb_replace",
      "type": "mongodb",
      "position": { "x": 550, "y": 50 },
      "data": {
        "label": "Migrar para Novo Schema",
        "operation": "findOneAndReplace",
        "config": {
          "connectionString": "mongodb://localhost:27017",
          "database": "crm"
        },
        "collection": "clientes",
        "query": {
          "_id": "{{clienteAntigo._id}}"
        },
        "document": {
          "schemaVersion": 2,
          "dados_pessoais": {
            "nome": "{{clienteAntigo.nome}}",
            "email": "{{clienteAntigo.email}}",
            "telefone": "{{clienteAntigo.telefone}}"
          },
          "endereco": {
            "rua": "{{clienteAntigo.endereco}}",
            "numero": "",
            "complemento": "",
            "cidade": "",
            "estado": "",
            "cep": ""
          },
          "status": "{{clienteAntigo.ativo}}",
          "timestamps": {
            "criado_em": "{{clienteAntigo.dataCriacao}}",
            "atualizado_em": "{{now}}",
            "migrado_em": "{{now}}"
          }
        },
        "responseVariable": "clienteNovo"
      }
    },
    {
      "id": "message_migrated",
      "type": "message",
      "position": { "x": 700, "y": 50 },
      "data": {
        "label": "Migrado",
        "parameters": {
          "message": "✅ Cliente migrado!\n\n👤 Nome: {{clienteNovo.dados_pessoais.nome}}\n📧 Email: {{clienteNovo.dados_pessoais.email}}\n🔢 Schema: v{{clienteNovo.schemaVersion}}"
        }
      }
    },
    {
      "id": "message_done",
      "type": "message",
      "position": { "x": 550, "y": 150 },
      "data": {
        "label": "Concluído",
        "parameters": {
          "message": "✅ Todos os clientes já estão no novo schema"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 850, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "mongodb_find_old" },
    { "source": "mongodb_find_old", "target": "condition_1" },
    { "source": "mongodb_replace", "target": "message_migrated" },
    { "source": "message_migrated", "target": "end_1" },
    { "source": "message_done", "target": "end_1" }
  ]
}

Saída esperada:

Sistema: ✅ Cliente migrado!

👤 Nome: João Silva
📧 Email: joao@example.com
🔢 Schema: v2

Resposta do Node

Quando documento é encontrado e substituído:

{
  "_id": "507f1f77bcf86cd799439011",
  "chave": "email",
  "smtp": {
    "host": "smtp.gmail.com",
    "port": 587
  },
  "dataAtualizacao": "2024-01-15T14:30:00.000Z"
}

Quando documento NÃO é encontrado (sem upsert):

null

Boas Práticas

SIM:

  • Use findOneAndReplace para substituição COMPLETA de documentos
  • Verifique se resultado não é null antes de acessar campos
  • Use upsert: true quando quiser "criar se não existir"
  • Busque documento antigo primeiro se precisar preservar alguns campos
  • Perfeito para reset de configurações ou migração de schema
  • O _id é SEMPRE preservado automaticamente

NÃO:

  • Não use quando quer atualizar apenas alguns campos (use UPDATE)
  • Não esqueça que TODOS os campos serão substituídos (exceto _id)
  • Não assuma que retornará um documento (pode ser null)
  • Não use para múltiplos documentos (opera apenas em 1)
  • Não inclua _id no novo documento (é preservado automaticamente)

Dicas

💡 Dica 1: Replace substitui TODO o documento - campos não incluídos serão REMOVIDOS

💡 Dica 2: O _id original é mantido automaticamente - não precisa incluir no novo documento

💡 Dica 3: Use FIND_ONE antes para buscar dados antigos que quer preservar

💡 Dica 4: Perfeito para migrar schemas: busca antigo → monta novo → replace

💡 Dica 5: Com upsert: true, cria documento novo se não encontrar

Próximos Nodes

MONGODB FIND_ONE_AND_UPDATE - Atualizar campos específicos (não substituir tudo) → MONGODB UPDATE - Atualizar múltiplos documentos → MONGODB FIND_ONE - Apenas buscar sem modificar → MONGODB INSERT - Criar novo documento