MongoDBでデータの登録、更新、削除について試してみる

「[MongoDBをDocker上に構築してみる](https://qiita.com/masato-sato/items/9f32e390a0b9b0f5e814)」で MongDBの環境を作成したので、データの登録、更新、削除について試してみたいと思います。
## データの登録について
```java:insertOne：1件だけ登録
> db.collection.insertOne(
    { key1: value1, key2: value2, ・・・ }
)
==================
> db_employee_info> db.employee.insertOne(
     {
        employeeName: '中田',
        created_date: new Date(),
        updated_date: new Date()
    })
{
  acknowledged: true,
  insertedId: ObjectId('668cbfbf05dbdfe7c7f3f550')
}

> db_employee_info> db.employee.find({employeeName: '中田'},{_id:0})
[
  {
    employeeName: '中田',
    created_date: ISODate('2024-07-09T04:42:39.438Z'),
    updated_date: ISODate('2024-07-09T04:42:39.438Z')
  }
]
```
```java:insertMany：複数件の登録
> db.collection.insertMany([
    { key1: value1, key2: value2, ・・・ },
    { key1: value1, key2: value2, ・・・ },
    { key1: value1, key2: value2, ・・・ }
])
==================
> db_employee_info> db.employee.insertMany([
    {
        employeeName: '鈴木',
        created_date: new Date(),
        updated_date: new Date()
    },
    {
        employeeName: '木下',
        created_date: new Date(),
        updated_date: new Date()
    },
    {
        employeeName: '高木',
        created_date: new Date(),
        updated_date: new Date()
    },
])
{
  acknowledged: true,
  insertedIds: {
    '0': ObjectId('668cc3a605dbdfe7c7f3f552'),
    '1': ObjectId('668cc3a605dbdfe7c7f3f553'),
    '2': ObjectId('668cc3a605dbdfe7c7f3f554')
  }
}
> db.employee.find({employeeName: /木/},{_id:0})
[
  {
    employeeName: '鈴木',
    created_date: ISODate('2024-07-09T04:59:18.087Z'),
    updated_date: ISODate('2024-07-09T04:59:18.087Z')
  },
  {
    employeeName: '木下',
    created_date: ISODate('2024-07-09T04:59:18.087Z'),
    updated_date: ISODate('2024-07-09T04:59:18.087Z')
  },
  {
    employeeName: '高木',
    created_date: ISODate('2024-07-09T04:59:18.087Z'),
    updated_date: ISODate('2024-07-09T04:59:18.087Z')
  }
]
```
### insertOne と insertMany の違い
単にデータを1件登録するか、複数するかの違いではありません。
登録するデータを1件で挿入するか、複数件で挿入するかの違いになります。
分かりづらいと思いますので、GUIツールで結果を表示してみました。

![nosqlbooster_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3763635/5c0340e2-ff53-5487-4685-6fa1a16b71e8.png)

Key列に「(10)」のデータが『insertOne』で挿入したデータです。
Key列に「(11)、(12)、(13)」のデータが『insertMany』で挿入したデータです。

## データの更新について
```java:updateOne：1件だけドキュメントを更新する
> db.collection.updateOne(
    { <検索条件> },
    { $set: { <更新内容> } }
)
==================
>  db.employee.find( { employeeName: '高橋' },{ _id: 0 } )
[ { employeeName: '高橋', age: 40 } ]

> db.employee.updateOne(
        { employeeName: '高橋' },
        { $set: { age: 50 } }
    )
{
  acknowledged: true,
  insertedId: null,
  matchedCount: 1,
  modifiedCount: 1,
  upsertedCount: 0
}

> db.employee.find( { employeeName: '高橋' },{ _id: 0 } )
[ { employeeName: '高橋', age: 50 } ]
```
```java:updateMany：複数件のドキュメントを更新する
> db.collection.updateMany(
    { <検索条件> },
    { $set: { <更新内容> } }
)
==================
>  db.employee.find({employeeName: /高/},{_id:0})
[
  { employeeName: '高橋', age: 50 },
  { employeeName: '高山', age: 42 },
  { employeeName: '吉高', age: 43 }
]

> db.employee.updateMany(
    { employeeName: /高/ },
    { $set: { age: 60 } }
    )
{
  acknowledged: true,
  insertedId: null,
  matchedCount: 3,
  modifiedCount: 3,
  upsertedCount: 0
}

> db.employee.find( { employeeName: /高/ },{ _id : 0 } )
[
  { employeeName: '高橋', age: 60 },
  { employeeName: '高山', age: 60 },
  { employeeName: '吉高', age: 60 }
]
```
### updateOneと updateMany の違い
updateManyを使用した場合は、検索条件にヒットしたデータ全てに対して更新します。
しかし、updateOneを使用した場合、検索条件にヒットしたデータの1件目に対してのみ更新を行います。


```
> db.employee.find( { employeeName: /高/ },{ _id: 0 } )
[
  { employeeName: '高橋', age: 60 },
  { employeeName: '高山', age: 60 },
  { employeeName: '吉高', age: 60 }
]

> db.employee.updateOne(
        { employeeName: /高/ },
        { $set: { age: 55 } } 
    )
{
  acknowledged: true,
  insertedId: null,
  matchedCount: 1,
  modifiedCount: 1,
  upsertedCount: 0
}

> db.employee.find( { employeeName: /高/ },{ _id: 0 } )
[
  { employeeName: '高橋', age: 55 },
  { employeeName: '高山', age: 60 },
  { employeeName: '吉高', age: 60 }
]
```
```java:replaceOne：ドキュメントの中を入れ替える
> db.collection.replaceOne(
    { <検索条件> },
    { <更新内容> }
)
==================
> db_employee_info> db.employee.find( { employeeName: '高橋' },{ _id: 0 } )
[ { employeeName: '高橋', age: 60 } ]

> db.employee.replaceOne(
        { employeeName: '高橋' },
        { employeeName: '高橋', skill: [ "Oracle","MySQL" ] }
    )
{
  acknowledged: true,
  insertedId: null,
  matchedCount: 1,
  modifiedCount: 1,
  upsertedCount: 0
}
> db.employee.find( { employeeName: '高橋' },{ _id:0 } )
[ { employeeName: '高橋', skill: [ 'Oracle', 'MySQL' ] } ]
```
ドキュメントの中を入れ替えるメソッドは『replaceOne』しかありません。

```java:配列に要素を追加する
> db.employee.find( { employeeName: '高橋' },{ _id:0 } )
[ { employeeName: '高橋', skill: [ 'Oracle', 'MySQL' ] } ]

> db.employee.updateOne(
        { employeeName: '高橋' },
        { $set: { "skill.2": 'MongDB' } }
    )
{
  acknowledged: true,
  insertedId: null,
  matchedCount: 1,
  modifiedCount: 1,
  upsertedCount: 0
}

> db.employee.find( { employeeName: '高橋' },{ _id: 0 } )
[
  {
    employeeName: '高橋',
    skill: [ 'Oracle', 'MySQL', 'MongDB' ]
  }
]
```

MongoDBには、updateとinsert を合わせもった upsert というものがあります。
updateOne, updateMany に "{ upsert: true}"を指定します。 
更新後に出力される『upsertedCount』は、データが登録されたときのみカウントされます。
```java:upsert：データの登録、または更新
> db.collection.updateOne(
    { <検索条件> },
    { <更新内容> },
    { upsert: true }
)
==================
> db.employee.find( { employeeName: '高橋' },{ _id: 0 } )
[
  {
    employeeName: '高橋',
    skill: [ 'Oracle', 'MySQL', 'MongDB', 'MongDB' ]
  }
]

> db.employee.updateOne(
        { employeeName: '高橋' },
        { $set: {age: 45 } },
        { upsert: true }
    )
{
  acknowledged: true,
  insertedId: null,
  matchedCount: 1,
  modifiedCount: 1,
  upsertedCount: 0
}
> db.employee.find( { employeeName: '高橋' },{ _id: 0 } )
[
  {
    employeeName: '高橋',
    skill: [ 'Oracle', 'MySQL', 'MongDB', 'MongDB' ],
    age: 45
  }
]
==================
> db.employee.updateOne(
        { employeeName: '横川' },
        { $set: {age: 40 } },
        { upsert: true }
    )
{
  acknowledged: true,
  insertedId: ObjectId('668ce891d2902517b339d59f'),
  matchedCount: 0,
  modifiedCount: 0,
  upsertedCount: 1
}

> db.employee.find( { employeeName: '横川' },{ _id: 0 } )
[ { employeeName: '横川', age: 40 } ]
```

## データの削除について
```java:1件だけドキュメントを削除する
> db.collection.deleteOne(
    { <検索条件> }
)
==================
> db.employee.find( { employeeName: /高/ },{ _id: 0 } )
[
  { employeeName: '高山', age: 60 },
  { employeeName: '吉高', age: 60 }
]

> db.employee.deleteOne( { employeeName: '高山' } )
{ acknowledged: true, deletedCount: 1 }

> db.employee.find({employeeName: /高/},{_id:0})
[
  {
    employeeName: '高木',
    created_date: ISODate('2024-07-09T04:59:18.087Z'),
    updated_date: ISODate('2024-07-09T04:59:18.087Z'),
    age: 55
  },
  {
    employeeName: '高橋',
    skill: [ 'Oracle', 'MySQL', 'MongDB', 'MongDB' ],
    age: 45
  },
  { employeeName: '吉高', age: 60 }
]
```
「deleteOne」は、検索条件にヒットしたデータの1件目に対して、削除を行います。

```java:複数件のドキュメントを削除する
> db.employee.find({employeeName: /田/},{_id:0}).count()
5

> db.employee.deleteMany({employeeName: //田/})
{ acknowledged: true, deletedCount: 5 }

> db.employee.find({employeeName: /田/},{_id:0}).count()
0

```

## 最後に
今回はここまでです。
update については、データを更新したり、要素が追加出来たりして、とても使い勝手のよいものだと感じました。登録、更新、削除について、便利な使い方があれば、コメントいただけると有り難いです。