[MongoDB] Version 4.4 新機能: unionWith を使ってみる
こんにちは、菊池です。
今週はMongoDBのオンラインカンファレンス、MongoDB Liveが開催されました。その中で、MongoDBの最新メジャーバージョンである、4.4についても多く触れられていました。MongoDB 4.4は現在、リリース候補版(以下RC版)が公開されており、検証などで利用可能になっています。(本番利用はしないようにしましょう)
今回は、MongoDB 4.4で追加される新規から、unionWithを使ったクエリ紹介します。unionWithはSQLのunionに相当し、複数のコレクション(RDBでいうところのテーブルに相当)に対するクエリ結果を結合することが可能です。
$unionWith を使ってみる
公式ドキュメントに従い、試してみます。
MongoDB 4.4 RC のインストールと接続
まずは、MondoDB 4,4 RCをインストールします。環境はCentOS7を利用しています。
まずはMogoDBのサーバ本体である、mongodをダウンロードしてインストールします。
$ wget https://repo.mongodb.org/yum/redhat/7/mongodb-org/testing/x86_64/RPMS/mongodb-org-server-4.4.0-0.1.rc9.el7.x86_64.rpm $ sudo yum install mongodb-org-server-4.4.0-0.1.rc9.el7.x86_64.rpm
続いて同様に、コマンドラインツールである、Mongo Shellをインストールします。
$ wget https://repo.mongodb.org/yum/redhat/7/mongodb-org/testing/x86_64/RPMS/mongodb-org-shell-4.4.0-0.1.rc9.el7.x86_64.rpm $ sudo yum install mongodb-org-shell-4.4.0-0.1.rc9.el7.x86_64.rpm
mongodを起動します。
$ sudo systemctl start mongod
接続してみましょう。
$ mongo localhost MongoDB shell version v4.4.0-rc9 connecting to: mongodb://127.0.0.1:27017/localhost?compressors=disabled&gssapiServiceName=mongodb Implicit session: session { "id" : UUID("245ce209-0fc8-4f9e-93e1-dd365e4871c3") } MongoDB server version: 4.4.0-rc9 Welcome to the MongoDB shell. For interactive help, type "help". For more comprehensive documentation, see http://docs.mongodb.org/ Questions? Try the support group http://groups.google.com/group/mongodb-user --- The server generated these startup warnings when booting: 2020-06-12T14:58:25.275+09:00: ***** SERVER RESTARTED ***** 2020-06-12T14:58:26.024+09:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted 2020-06-12T14:58:26.025+09:00: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. We suggest setting it to 'never' 2020-06-12T14:58:26.025+09:00: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. We suggest setting it to 'never' --- --- Enable MongoDB's free cloud-based monitoring service, which will then receive and display metrics about your deployment (disk utilization, CPU, operation statistics, etc). The monitoring data will be available on a MongoDB website with a unique URL accessible to you and anyone you share the URL with. MongoDB may use this information to make product improvements and to suggest MongoDB products and deployment options to you. To enable free monitoring, run the following command: db.enableFreeMonitoring() To permanently disable this reminder, run the following command: db.disableFreeMonitoring() --- >
無事、接続できました。
$unionWith を使ったクエリ
まずは、suppliers
コレクションにデータを入れます。
> db.suppliers.insertMany([ ... { _id: 1, supplier: "Aardvark and Sons", state: "Texas" }, ... { _id: 2, supplier: "Bears Run Amok.", state: "Colorado"}, ... { _id: 3, supplier: "Squid Mark Inc. ", state: "Rhode Island" }, ... ]) { "acknowledged" : true, "insertedIds" : [ 1, 2, 3 ] }
同様に、warehouses
コレクションにもデータを入れておきます。
> db.warehouses.insertMany([ ... { _id: 1, warehouse: "A", region: "West", state: "California" }, ... { _id: 2, warehouse: "B", region: "Central", state: "Colorado"}, ... { _id: 3, warehouse: "C", region: "East", state: "Florida" }, ... ]) { "acknowledged" : true, "insertedIds" : [ 1, 2, 3 ] }
各コレクション、このようにデータが入りました。
> db.suppliers.find() { "_id" : 1, "supplier" : "Aardvark and Sons", "state" : "Texas" } { "_id" : 2, "supplier" : "Bears Run Amok.", "state" : "Colorado" } { "_id" : 3, "supplier" : "Squid Mark Inc. ", "state" : "Rhode Island" } >
> db.warehouses.find() { "_id" : 1, "warehouse" : "A", "region" : "West", "state" : "California" } { "_id" : 2, "warehouse" : "B", "region" : "Central", "state" : "Colorado" } { "_id" : 3, "warehouse" : "C", "region" : "East", "state" : "Florida" } >
aggregateパイプラインで、unionWithを使って、stateを取得してみます。
> db.suppliers.aggregate([ ... { $project: { state: 1, _id: 0 } }, ... { $unionWith: { coll: "warehouses", pipeline: [ { $project: { state: 1, _id: 0 } } ]} } ... ]) { "state" : "Texas" } { "state" : "Colorado" } { "state" : "Rhode Island" } { "state" : "California" } { "state" : "Colorado" } { "state" : "Florida" } >
この結果だと、"state" : "Colorado" が重複します。(SQLにおけるUNION ALLに近い結果です)重複を除くため、$groupにてstateでグループ化します。
> db.suppliers.aggregate([ ... { $project: { state: 1, _id: 0 } }, ... { $unionWith: { coll: "warehouses", pipeline: [ { $project: { state: 1, _id: 0 } } ]} }, ... { $group: { _id: "$state" } } ... ]) { "_id" : "Texas" } { "_id" : "Florida" } { "_id" : "Rhode Island" } { "_id" : "Colorado" } { "_id" : "California" } >
重複が含まれない結果が取れました。
最後に
MongoDB 4.4 の新機能、unionWithを使ったクエリを試してみました。クエリの幅が広がることで、アプリケーションの開発がやりやすくなるかと思います。4.4が正式リリースされたらぜひアップデートしていきましょう。