Partilhar via


$setOnInsert (operador de atualização de campo)

Aplica-se a: MongoDB vCore

O $setOnInsert operador é usado para definir valores de campo somente quando uma operação de upsert resulta na inserção de um novo documento. Se o documento já existir e estiver a ser atualizado, o $setOnInsert operador não produz efeitos. Este operador é particularmente útil para definir valores padrão ou dados de inicialização que só devem ser aplicados ao criar novos documentos.

Sintaxe

A sintaxe para o operador é a $isArray seguinte:

{
  $setOnInsert: {
    <field1>: <value1>,
    <field2>: <value2>,
    ...
  }
}

Parâmetros

Descrição
field O nome do campo a ser definido somente na inserção. Pode ser um campo de nível superior ou usar notação de pontos para campos aninhados.
value O valor a atribuir ao campo somente ao inserir um novo documento. Pode ser qualquer tipo BSON válido.

Exemplo

Vamos entender o uso com json de exemplo do conjunto de stores dados para operações de upsert.

Exemplo 1: Utilização básica do $setOnInsert

Suponha que você queira criar ou atualizar um registro de loja, mas defina apenas determinados campos de inicialização ao criar um novo armazenamento.

// First, let's try upserting a store that doesn't exist
db.stores.updateOne(
  { "_id": "new-store-001" },
  {
    $set: {
      "name": "TechWorld Electronics - Downtown",
      "sales.totalSales": 0
    },
    $setOnInsert: {
      "createdDate": new Date(),
      "status": "new",
      "staff.totalStaff.fullTime": 0,
      "staff.totalStaff.partTime": 0,
      "version": 1
    }
  },
  { upsert: true }
)

Saída:

{
  acknowledged: true,
  insertedId: 'new-store-001',
  matchedCount: 0,
  modifiedCount: Long("0"),
  upsertedCount: 1
}

Como o documento com _id: "new-store-001" não existe, isso criará um novo documento:

{
  "_id": "new-store-001",
  "name": "TechWorld Electronics - Downtown",
  "sales": {
    "totalSales": 0
  },
  "createdDate": ISODate("2025-06-05T10:30:00.000Z"),
  "status": "new",
  "staff": {
    "totalStaff": {
      "fullTime": 0,
      "partTime": 0
    }
  },
  "version": 1
}

Exemplo 2: $setOnInsert com documento existente

Agora, vamos tentar atualizar o mesmo documento novamente com valores diferentes:

db.stores.updateOne(
  { "_id": "new-store-001" },
  {
    $set: {
      "name": "TechWorld Electronics - Downtown Branch",
      "sales.totalSales": 5000
    },
    $setOnInsert: {
      "createdDate": new Date(),
      "status": "updated",
      "staff.totalStaff.fullTime": 10,
      "staff.totalStaff.partTime": 5,
      "version": 2
    }
  },
  { upsert: true }
)

Como o documento já existe, apenas as $set operações serão aplicadas, e $setOnInsert serão ignoradas:

{
  "_id": "new-store-001",
  "name": "TechWorld Electronics - Downtown Branch",
  "sales": {
    "totalSales": 5000
  },
  "createdDate": ISODate("2025-06-05T10:30:00.000Z"),
  "status": "new",
  "staff": {
    "totalStaff": {
      "fullTime": 0,
      "partTime": 0
    }
  },
  "version": 1
}

Exemplo 3: $setOnInsert complexas com objetos aninhados

Você pode usar $setOnInsert para inicializar estruturas aninhadas complexas:

db.stores.updateOne(
  { "name": "Gaming Paradise - Mall Location" },
  {
    $set: {
      "location.lat": 35.6762,
      "location.lon": 139.6503
    },
    $setOnInsert: {
      "_id": "gaming-store-mall-001",
      "createdDate": new Date(),
      "status": "active",
      "staff": {
        "totalStaff": {
          "fullTime": 8,
          "partTime": 12
        },
        "manager": "Alex Johnson",
        "departments": ["gaming", "accessories", "repairs"]
      },
      "sales": {
        "totalSales": 0,
        "salesByCategory": []
      },
      "operatingHours": {
        "weekdays": "10:00-22:00",
        "weekends": "09:00-23:00"
      },
      "metadata": {
        "version": 1,
        "source": "store-management-system"
      }
    }
  },
  { upsert: true }
)

Exemplo 4: Usando $setOnInsert com matrizes

Você pode inicializar matrizes e estruturas de dados complexas:

db.stores.updateOne(
  { "address.city": "New Tech City" },
  {
    $set: {
      "name": "Future Electronics Hub",
      "sales.totalSales": 25000
    },
    $setOnInsert: {
      "_id": "future-electronics-001",
      "establishedDate": new Date(),
      "categories": ["electronics", "gadgets", "smart-home"],
      "promotionEvents": [],
      "ratings": {
        average: 0,
        count: 0,
        reviews: []
      },
      "inventory": {
        lastUpdated: new Date(),
        totalItems: 0,
        lowStockAlerts: []
      }
    }
  },
  { upsert: true }
)

Importante

O $setOnInsert operador só produz efeitos durante as operações de upsert ({ upsert: true }).

Se o documento existir, $setOnInsert os campos serão completamente ignorados.

$setOnInsert é comumente usado para lidar com $set cenários de atualização e inserção em uma única operação.

Você pode combinar $setOnInsert com outros operadores de atualização como $inc, $push, etc.

O $setOnInsert operador é ideal para definir carimbos de data/hora de criação, valores padrão e dados de inicialização.