# Обновление существующих документов с помощью методов update

## 1. Метод updateOne

Этот метод обновляет только первый документ, соответствующий фильтру.

Что делает:
- Если документ найден:
  - Меняет указанные поля с помощью операторов ($set, $inc и т.д.). 
  - Если указанных полей нет, они добавляются.
- Если документ не найден и включён upsert: true, создаётся новый документ, который:
  - Содержит данные из фильтра.
  - Содержит данные, указанные в $set (или других операторах).
- Если документ не найден и `upsert` выключен (`{ upsert: false }`) или вовсе отсутствует, то апдейт будет попросту проигнорирован.

Пример:
```
db.collection.updateOne(
  { name: "Alice" }, // Фильтр
  { $set: { age: 30 } }, // Обновление
  { upsert: true } // Опция upsert
);
```

Результат:
- Если документ `{ name: "Alice" }` найден:
```
{ "name": "Alice", "age": 30 }
```
- Если документа нет:
```
{ "name": "Alice", "age": 30 }
```

## 2. Метод updateMany

Этот метод обновляет все документы, которые соответствуют фильтру.

- Что делает:
  - Если документы найдены:
  - Меняет указанные поля с помощью операторов.
  - Если указанных полей нет, они добавляются.
- Если ни одного документа не найдено и включён upsert: true, создаётся один новый документ:
  - С данными из фильтра.
  - С данными из $set (или других операторов).

Пример:
```
db.collection.updateMany(
  { city: "New York" }, // Фильтр
  { $set: { visited: true } }, // Обновление
  { upsert: true } // Опция upsert
);
```

Результат:
- Если есть несколько документов с city: "New York":
```
{ "city": "New York", "visited": true }
```
Для каждого найденного документа.

- Если документов с city: "New York" нет:
```
{ "city": "New York", "visited": true }
```

## 3. Метод replaceOne

Этот метод заменяет весь документ на новый, если он найден.

- Что делает:
  - Если документ найден:
    - Полностью заменяет его содержимое на новый документ.
    - Старые данные удаляются, если они не указаны в новом документе.
- Если документ не найден и включён upsert: true, создаётся новый документ:
  - С данными из фильтра.
  - С данными, переданными для замены.

Пример:
```
db.collection.replaceOne(
  { name: "Alice" }, // Фильтр
  { name: "Alice", age: 30, hobby: "reading" }, // Новый документ
  { upsert: true } // Опция upsert
);
```
Результат:
- Если документ { name: "Alice" } найден:
```
{ "name": "Alice", "age": 30, "hobby": "reading" }
```
- Если документа нет:
```
{ "name": "Alice", "age": 30, "hobby": "reading" }
```

| Метод        | Действие                                    | Количество документов  | Замена/Изменение полей | Поддержка `upsert` |
|--------------|---------------------------------------------|-------------------------|-------------------------|---------------------|
| `updateOne`  | Обновляет первый найденный документ         | 1                       | Изменяет указанные поля | Да                 |
| `updateMany` | Обновляет все найденные документы           | Все                     | Изменяет указанные поля | Да                 |
| `replaceOne` | Полностью заменяет первый найденный документ| 1                       | Полная замена документа | Да                 |


- updateOne:
  - Меняет или добавляет указанные поля.
  - Создаёт новый документ при upsert: true.

- updateMany:
  - Обновляет все документы, соответствующие фильтру.
  - Создаёт один новый документ при upsert: true, если ничего не найдено.

- replaceOne:
  - Полностью заменяет документ.
  - Создаёт новый документ при upsert: true.

Выбор метода зависит от задачи:
- Если нужно обновить одно поле в одном документе — updateOne. 
- Если нужно массово обновить документы — updateMany.
- Если требуется полная замена документа — replaceOne.


## Способы обновления документов

### 1. Операторы для изменения полей
 
`$set`
Устанавливает указанное значение для поля, добавляет поле, если его не существует.

```
{ $set: { age: 30 } }
```

`$unset`
Удаляет указанное поле из документа.

```
{ $unset: { age: "" } }
```

`$rename`
Переименовывает поле.

```
{ $rename: { oldName: "newName" } }
```

`$inc`
Увеличивает или уменьшает числовое значение на указанную величину.

```
{ $inc: { views: 1 } }
```

`$mul`
Умножает числовое значение поля на указанное число.

```
{ $mul: { price: 1.2 } }
```

### 2. Операторы для массивов

`$push`
Добавляет элемент в массив.

```
{ $push: { tags: "new_tag" } }
```

`$addToSet`
Добавляет элемент в массив, но только если его ещё нет.

```
{ $addToSet: { tags: "unique_tag" } }
```

`$pop`
Удаляет первый или последний элемент массива.
- Значение:
  - удалить последний: 1
  - удалить первый: -1

```
{ $pop: { tags: 1 } }
```

`$pull`
Удаляет элементы из массива, соответствующие условию.

```
{ $pull: { tags: "unwanted_tag" } }
```

`$pullAll`
Удаляет сразу несколько указанных элементов массива.

```
{ $pullAll: { tags: ["tag1", "tag2"] } }
```

`$each (с $push)`
Добавляет несколько элементов в массив.

```
{ $push: { tags: { $each: ["tag1", "tag2"] } } }
```

`$slice (с $push)`
Ограничивает размер массива после добавления новых элементов.

```
{ $push: { tags: { $each: ["tag1", "tag2"], $slice: 5 } } }
```

`$position (с $push)`
Указывает позицию, куда добавить элементы.

```
{ $push: { tags: { $each: ["tag1", "tag2"], $position: 1 } } }
```

### 3. Операторы для замены значений

`$min`
Обновляет значение поля, если новое значение меньше текущего.

```
{ $min: { age: 18 } }
```

`$max`
Обновляет значение поля, если новое значение больше текущего.

```
{ $max: { age: 65 } }
```

`$currentDate`
Устанавливает поле на текущую дату/время.

- Формат:
  - `true` — сохранить значение как Date.
  - `{ $type: "timestamp" }` — сохранить значение как Timestamp.

```
{ $currentDate: { lastModified: true, createdAt: { $type: "timestamp" } } }
```


