Oracle Database API for MongoDBを使用してmongoshからJSON Relational Dualityビューにアクセスする

# はじめに

Oracle Database API for MongoDBを使用してmongoshからOracle Database 23aiにアクセスし、 JSON Relational Dualityビューに対してデータ操作を行ってみました。

こちらの内容は、以下の記事を前提としています。

https://qiita.com/500InternalServerError/items/d6d24e201c32ccf69a96

https://qiita.com/500InternalServerError/items/e0ced3dfc8d958f03059

:::note warn
注意
こちらの記事の内容はあくまで個人の実験メモ的な内容のため、こちらの内容を利用した場合のトラブルには一切責任を負いません。
また、こちらの記事の内容を元にしたOracleサポートへの問い合わせはご遠慮ください。
:::


# 1. mongoshからOracle Database 23aiに接続

mongoshからユーザtestuserとしてOracle Database 23aiに接続します。
```
[opc@db23ai ~]$ mongosh --tlsAllowInvalidCertificates 'mongodb://testuser@localhost:27017/testuser?authMechanism=PLAIN&authSource=$external&tls=false&retryWrites=false&loadBalanced=true'
Enter password: ************
Current Mongosh Log ID:	67ef3a4fab7921e3256b140a
Connecting to:		mongodb://<credentials>@localhost:27017/testuser?authMechanism=PLAIN&authSource=%24external&tls=false&retryWrites=false&loadBalanced=true&tlsAllowInvalidCertificates=true&appName=mongosh+2.4.2
Using MongoDB:		4.2.14
Using Mongosh:		2.4.2

For mongosh info see: https://www.mongodb.com/docs/mongodb-shell/

testuser> 
```

show collectionsで利用可能なコレクションを確認します。
```
testuser> show collections;
COURSE
testuser> 
```

JSON Relational DualityビューCOURSEがコレクションとして表示されました。

# 2. mongoshから検索を実行する

find()メソッドでCOURSEの内容を確認します。
```
testuser> db.COURSE.find()
[
  {
    _id: 'MATH101',
    name: 'Algebra',
    Notes: 'Prerequisite for Advanced Algebra',
    teacher: { name: 'Abdul J.', teacherId: 101 },
    students: [],
    creditHours: 3,
    courseId: 'MATH101',
    _metadata: {
      etag: Binary.createFromBase64('FjfgobIlvFPoLOiEyXh4AQ==', 0),
      asof: Binary.createFromBase64('AAAAAAEL5S0=', 0)
    }
  },
  {
    _id: 'MATH102',
    name: 'Calculus',
    Notes: null,
    teacher: { name: 'Abdul J.', teacherId: 101 },
    students: [ { name: 'Ming L.', studentId: 10 } ],
    creditHours: 4,
    courseId: 'MATH102',
    _metadata: {
      etag: Binary.createFromBase64('pLp7kzOr0ZuWvB/h8gs4dw==', 0),
      asof: Binary.createFromBase64('AAAAAAEL5S0=', 0)
    }
  },
  {
    _id: 'CS101',
    name: 'Algorithms',
    Notes: null,
    teacher: { name: 'Betty Z.', teacherId: 102 },
    students: [],
    creditHours: 5,
    courseId: 'CS101',
    _metadata: {
      etag: Binary.createFromBase64('qGw+41OjrynyBZcGpHmZXQ==', 0),
      asof: Binary.createFromBase64('AAAAAAEL5S0=', 0)
    }
  },
  {
    _id: 'CS102',
    name: 'Data Structures',
    Notes: null,
    teacher: { name: 'Betty Z.', teacherId: 102 },
    students: [
      { name: 'Donald P.', studentId: 1 },
      { name: 'Elena H.', studentId: 2 },
      { name: 'Hye E.', studentId: 5 },
      { name: 'Jatin S.', studentId: 7 }
    ],
    creditHours: 3,
    courseId: 'CS102',
    _metadata: {
      etag: Binary.createFromBase64('HoBKq9HogIY4pPTKLr9ntQ==', 0),
      asof: Binary.createFromBase64('AAAAAAEL5S0=', 0)
    }
  },
  {
    _id: 'MATH103',
    name: 'Advanced Algebra',
    Notes: 'Very Difficult',
    teacher: { name: 'Colin J.', teacherId: 103 },
    students: [
      { name: 'Francis K.', studentId: 3 },
      { name: 'Georgia D.', studentId: 4 },
      { name: 'Ileana D.', studentId: 6 },
      { name: 'Katie H.', studentId: 8 },
      { name: 'Luis F.', studentId: 9 }
    ],
    creditHours: 3,
    courseId: 'MATH103',
    _metadata: {
      etag: Binary.createFromBase64('flFdo9J3L4MTV/0nARLjkQ==', 0),
      asof: Binary.createFromBase64('AAAAAAEL5S0=', 0)
    }
  }
]
testuser> 
```

find()メソッドで、_idがMATH103のドキュメントを取得します。
```
testuser> db.COURSE.find({_id:"MATH103"})
[
  {
    _id: 'MATH103',
    name: 'Advanced Algebra',
    Notes: 'Very Difficult',
    teacher: { name: 'Colin J.', teacherId: 103 },
    students: [
      { name: 'Francis K.', studentId: 3 },
      { name: 'Georgia D.', studentId: 4 },
      { name: 'Ileana D.', studentId: 6 },
      { name: 'Katie H.', studentId: 8 },
      { name: 'Luis F.', studentId: 9 }
    ],
    creditHours: 3,
    courseId: 'MATH103',
    _metadata: {
      etag: Binary.createFromBase64('Os6f5VbyQjkc7m/hg8UVXQ==', 0),
      asof: Binary.createFromBase64('AAAAAAEL5hM=', 0)
    }
  }
]
testuser> 
```
_idがMATH103のドキュメントが取得できました。

# 3. mongoshから更新（Update）を実行する

updateOne()メソッドで、_idがMATH103のドキュメントのNotesの値をEasyに変更します。
```
testuser> db.COURSE.updateOne(
...    {_id:"MATH103"},
...    {
...      $set: { Notes : "Easy" },
...    }
... )
{
  acknowledged: true,
  insertedId: null,
  matchedCount: 1,
  modifiedCount: 1,
  upsertedCount: 0
}
testuser> 
```

find()メソッドで、_idがMATH103のドキュメントを取得します。
```
testuser> db.COURSE.find({_id:"MATH103"})
[
  {
    _id: 'MATH103',
    name: 'Advanced Algebra',
    Notes: 'Easy',
    teacher: { name: 'Colin J.', teacherId: 103 },
    students: [
      { name: 'Francis K.', studentId: 3 },
      { name: 'Georgia D.', studentId: 4 },
      { name: 'Ileana D.', studentId: 6 },
      { name: 'Katie H.', studentId: 8 },
      { name: 'Luis F.', studentId: 9 }
    ],
    creditHours: 3,
    _metadata: {
      etag: Binary.createFromBase64('zvbWVTQtxf56GjjRnj9Tog==', 0),
      asof: Binary.createFromBase64('AAAAAAEL5zI=', 0)
    }
  }
]
testuser> 
```
_idがMATH103のドキュメントのNotesの値がEasyに変更されていることが確認できました。

# 4. SQL*Plusから変更内容を確認する

SQL*PlusからユーザtestuserとしてOracle Database 23aiに接続します。

JSON Relational Dualityビューcourseから_idがMATH103のドキュメントを検索します。

```
SQL> SELECT data FROM course c
  2  WHERE c.data."_id" = 'MATH103';

DATA
--------------------------------------------------------------------------------
{"_id":"MATH103","_metadata":{"etag":"CEF6D655342DC5FE7A1A38D19E3F53A2","asof":"
00000000010C2DD9"},"name":"Advanced Algebra","Notes":"Easy","teacher":{"name":"C
olin J.","teacherId":103},"students":[{"name":"Francis K.","studentId":3},{"name
":"Georgia D.","studentId":4},{"name":"Ileana D.","studentId":6},{"name":"Katie
H.","studentId":8},{"name":"Luis F.","studentId":9}],"creditHours":3,"courseId":
"MATH103"}


SQL>
```

JSON_SERIALIZEファンクションを使用して、見やすいように整形して出力します。
```
SQL> SELECT JSON_SERIALIZE(data PRETTY) FROM course c
  2  WHERE c.data."_id"  = 'MATH103';

JSON_SERIALIZE(DATAPRETTY)
------------------------------------------------------------------------------------------------------------------------
{
  "_id" : "MATH103",
  "_metadata" :
  {
    "etag" : "CEF6D655342DC5FE7A1A38D19E3F53A2",
    "asof" : "00000000010C2EAD"
  },
  "name" : "Advanced Algebra",
  "Notes" : "Easy",
  "teacher" :
  {
    "name" : "Colin J.",
    "teacherId" : 103
  },
  "students" :
  [
    {
      "name" : "Francis K.",
      "studentId" : 3
    },
    {
      "name" : "Georgia D.",
      "studentId" : 4
    },
    {
      "name" : "Ileana D.",
      "studentId" : 6
    },
    {
      "name" : "Katie H.",
      "studentId" : 8
    },
    {
      "name" : "Luis F.",
      "studentId" : 9
    }
  ],
  "creditHours" : 3,
  "courseId" : "MATH103"
}


SQL> 
```
JSON Relational DualityビューcourseにSQLでアクセスしても、_idがMATH103のドキュメントのNotesの値がEasyに変更されていることが確認できました

JSON Relational Dualityビューcourseのベースとなっている表course_rootの内容を確認してみます。
```
SQL> col name for a20
SQL> col notes for a35
SQL> col course_id for a10
SQL> set linesize 120
SQL> SELECT * FROM course_root;

NAME		         NOTES				                 COURSE_ID  CREDIT_HOURS TEACHER_ID_COURSE_TEACHER
-------------------- ----------------------------------- ---------- ------------ -------------------------
Algebra 	         Prerequisite for Advanced Algebra	 MATH101	           3		               101
Calculus						                         MATH102	           4		               101
Algorithms						                         CS101		           5		               102
Data Structures 					                     CS102		           3		               102
Advanced Algebra     Easy				                 MATH103	           3		               103

SQL>
```

course_idがMATH103の行のnotes列の値が「Easy」に更新されていることが確認できました。