今回は、前回
検証環境
今回はDockerで建てたMySQLを使用します。以下のコマンドでDockerを建ててローカルからアクセスをします。
% docker run --platform linux/x86_64 -p 127.0.0.1:3307:3306 -e MYSQL_ROOT_PASSWORD=my-secret-pw -e MYSQL_USER=kk2170 -e MYSQL_PASSWORD=my-secret-pw -d mysql:8.0.36
今回も前回や第214回と同様に、DockerのイメージにあるMySQL Shellを使用して接続をしていきます。まずは対話モードでも実行を行いたいので、対話モードでJavaScriptを実行します。
立ち上げたDockerコンテナの中に入るため、コンテナIDを調べます。
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5480636b729f mysql:8.0.36 "docker-entrypoint.s…" 12 seconds ago Up 10 seconds 33060/tcp, 127.0.0.1:3307->3306/tcp elastic_lederberg
続いて、docker execコマンドを使用してMySQLのコンテナ内部に入ります。その後、mysqlshコマンドでログインを済ませます。
$ docker exec -it 5480636b729f bash # mysqlsh 《中略》 MySQL localhost JS >
中略された部分に関して詳細が知りたい場合は、第214回で説明を行っているため、そちらを参照してください。執筆時点では、以下の通りMySQL 8.
MySQL localhost JS > \sql select version(); Fetching global names for auto-completion... Press ^C to stop. +-----------+ | version() | +-----------+ | 8.0.36 | +-----------+ 1 row in set (0.0001 sec)
JSONデータを操作してみる
さて今回は前回作成したテーブルに書き込み、読み込み、更新、削除といった基本的なCRUD操作を行っていきます。前回最後に作成したテーブルをもう一度作成してみましょう。
MySQL localhost JS > var mySession = mysqlx.getSession('root:my-secret-pw@localhost'); MySQL localhost JS > mySession.createSchema('test'); <Schema:test> MySQL localhost JS > mySession.getSchema("test").createCollection("json_table"); <Collection:json_table>
これでtestデータベースにjson_
それでは、一旦Collectionのオブジェクトを取得してみて、どのような関数があるのか確認してみましょう。データベースSchemaに対してgetCollectionを行うと、テーブルを取得することができます。
MySQL localhost JS > var table = mySession.getSchema("test").getCollection("json_table");
取得できたtableオブジェクトをObject.
の引数にして、どのようなメソッドが生えているか確認してみましょう。
MySQL localhost JS > Object.keys(table); [ "name", "session", "schema", "add", "addOrReplaceOne", "count", "createIndex", "dropIndex", "existsInDatabase", "find", "getName", "getOne", "getSchema", "getSession", "help", "modify", "remove", "removeOne", "replaceOne" ]
このようなメソッドが用意されていることがわかります。今回だけでは全部のメソッドに関して説明しきれませんが、便利なメソッドもありますので活用していきましょう。これから基本的なコレクションの操作方法に絞って紹介していきます。
JSONを書き込みして値を確認する
今回は、addメソッドを使って書き込みをしていきます。addメソッドはテーブルに対して行うことで操作が可能となります。
さて、まずは書き込みを行う前に状況を確認してみましょう。データの検索には、findメソッドを使用して確認することができます。引数に入れた値に応じて検索ができるのですが、今回は何も入れずに実行してみます。この場合、WHERE句を付けなかったのと同じ状態になります。
MySQL localhost JS > table.find() Empty set (0.0005 sec)
テーブルを作ったばかりなので、何も見つかりませんでした。続いて、addメソッドを使ってデータを登録してみましょう。idに1という値を持ったJSONを登録してみます。
MySQL localhost JS > table.add({id: 1}) Query OK, 1 item affected (0.0048 sec)
このデータを取得してみましょう。findメソッドを使って取得してみます。
MySQL localhost test JS > table.find() { "id": 1, "_id": "000065ea84d50000000000000003" }
_idという値が増えています。これは、テーブル定義にあった主キーとして定義されていた_idが出力されています。今回は指定を行わなかったため自動で生成されていますが、これは自分で定義することもできます。
続いて、同様にaというキーと"test"という値と_idというキーと"primary_
MySQL localhost test JS > table.add({a: "test", _id: "primary_key"}) Query OK, 1 item affected (0.0155 sec) MySQL localhost test JS > table.find() { "id": 1, "_id": "000065ea84d50000000000000003" } { "a": "test", "_id": "primary_key" }
このように追加できたことがわかります。
格納されているJSONを更新する
続いて更新をしてみましょう。更新にはmodifyメソッドを使います。追加と削除のパターンで、それぞれ考えてみましょう。
"id"が1のオブジェクトに対して"kk2170"という値を持つnameというキーを追加してみましょう。modifyの引数に検索条件を入れることで、特定のオブジェクトに対しての操作を行うことができます。対象に対してsetメソッドをチェーンして、登録したい値を入れることで更新することができます。
MySQL localhost test JS > table.modify("id = 1").set("name", "kk2170") MySQL localhost test JS > table.find("id = 1") { "id": 1, "_id": "000065ea84d50000000000000003", "name": "kk2170" } 1 document in set (0.0008 sec)
modifyをして更新した結果が上記になります。今度は、逆に登録したキーを削除してみたいと思います。その場合はunsetが使用できます。
MySQL localhost test JS > table.modify("id = 1").unset("name") Query OK, 1 item affected (0.0148 sec) Rows matched: 1 Changed: 1 Warnings: 0 MySQL localhost test JS > table.find("id = 1") { "id": 1, "_id": "000065ea84d50000000000000003" } 1 document in set (0.0007 sec)
このように、属性の削除ができていることがわかります。
格納したJSONを削除する
続いてオブジェクト全体を削除してみようと思います。今回使用するのはremoveメソッドになります。removeメソッドも同様に検索条件を引数として渡すことで、オブジェクトの削除を行うことができます。今回はid=1を指定して削除してみましょう。
MySQL localhost test JS > table.remove("id = 1") Query OK, 1 item affected (0.0062 sec) MySQL localhost test JS > table.find("id = 1") Empty set (0.0012 sec)
このように削除されていることがわかります。ではデータベースの値全体を削除してみましょう。まずはfindの時のように、引数を空の状態でメソッドを実行してみましょう。
MySQL localhost test JS > table.remove() CollectionRemove.remove: Invalid number of arguments, expected 1 but got 0 (ArgumentError)
引数の数が間違っているというエラーが返ってきました。removeを実行するには必ず1つ条件式が必要なようです。ここで思い出すと良いのは、SQLでもWHERE句が常にtrueになる条件式を指定すると、すべての値が取得できるということです。試しにSQLで以下のSQLを実行してみます。
MySQL localhost test JS > \sql select * from `json_table` where true +-------------------------------------+--------------------------+--------------------+ | doc | _id | _json_schema | +-------------------------------------+--------------------------+--------------------+ | {"a": "test", "_id": "primary_key"} | 0x7072696D6172795F6B6579 | {"type": "object"} | +-------------------------------------+--------------------------+--------------------+ 1 row in set (0.0005 sec) MySQL localhost test JS > \sql select * from `json_table` +-------------------------------------+--------------------------+--------------------+ | doc | _id | _json_schema | +-------------------------------------+--------------------------+--------------------+ | {"a": "test", "_id": "primary_key"} | 0x7072696D6172795F6B6579 | {"type": "object"} | +-------------------------------------+--------------------------+--------------------+ 1 row in set (0.0007 sec)
このようにtrueを指定すると、何も指定してないのと同じ結果になることがわかります。つまり全件削除したい場合、"true"と指定すれば良さそうに思えます。試してみましょう。
MySQL localhost test JS > table.remove("true") Query OK, 1 item affected (0.0141 sec) MySQL localhost test JS > table.find() Empty set (0.0006 sec)
無事削除できていることがわかりました。
まとめ
今回は、MySQL ShellでJavaScriptで書いたコードでデータを取得書き込み削除する方法を紹介させていただきました。_id等少し気になる動作もありますが、基本的な操作はNoSQLを扱うように使用できることが紹介できたと思います。JSON型を扱うには、SQLよりもやはりJSONの方が使いやすい場面もあると思いますので、ぜひ活用してみましょう。