0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

MongoDB Shellで複数のDBに対し、一気に更新することは出来ないかなーって考えたのでその際の備忘録です。
一つのDBに対する更新はともかく、それを複数のDBに展開しようとすると手作業だとかなり面倒ですしね。

構造が同じDBが複数存在している時にしか使えないので、他の人にとって役立つか?というと微妙ですが…

実際の処理

さて、早速ですが本題のスクリプトになります。

const dbNames = db.getMongo().getDBNames();
dbNames.forEach((dbName) => {
  const currentDB = db.getSiblingDB(dbName);
  // 以下、各DBで実行したい処理を行う
  currentDB.any_collection.updateMany({}, { $set: { test: true } });
  currentDB.any_collection.createIndex({ key: 1 }, { name: 'INDEX_TEST' });
  // ここまで
});

db.getMongo()でMongoDBのインスタンスを取得し、getDBNames()でDB名を配列で取得します。
あとは取得したDB名をループし、db.getSiblingDB(dbName)で対象DBのオブジェクトを取得して各クエリを実行していきます。

こう見ると単純ではありますが、通常ではまず使わないようなメソッドを使うので普通にMongoDBを使っているだけだと知ることは恐らくほぼ無いです。
通常のアプリでDB跨ぐような処理ってまずやらないし…
全部のDBだけじゃなくて一部特定のDBだけでいいなら、上記のdbNamesに固定で配列を記述するなど応用すれば使える機会はもっと増えそうです。

getDBNames()DBに接続しているユーザーが権限を持っているDB名を返します。
つまり、ユーザーによってはadminconfigなどのDB名も取得され、処理の対象となってしまいます。
DB権限を制限しているユーザーで接続する、if文で対象のDBを判定するなど対策の上使用してください。

余談:試したこと

本題は終わっていますが、上記に辿り着くまでの経緯も備忘録として記載しておきます。

まずDB名を取得する方法ですが、単にリストが見えればいいのであればshow dbsというコマンドもあります。

> show dbs
< admin    40.00 KiB
  config   96.00 KiB
  local    72.00 KiB
  sandbox  72.00 KiB

ただこれは変数で受け取れないので、後続の処理に使うことはできません。あくまで見るだけですね。

また、DBの切り替えならuse DB名というコマンドもあります。
普通にMongoDB ShellでDBの切り替えを行うならこのコマンドですね。

> use sandbox
< switched to db sandbox

最初はdb.getSiblingDB(dbName)の代わりにこれを使おうとしていましたが、後続のクエリが実行されないのでこれも今回は使えませんでした。
普通の切り替えならuseでよいので、用途によってちゃんと使い分けていきたいですね。

参考リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?