昨日の夜に縄跳びに出掛けようと思ったところ、雨がパラパラしてきて諦めた。今週は天気が悪いからあまり外で運動できないかもしれない。

今日の運動は腕立て,スクワットをした。統計を 運動の記録 にまとめる。

mongosh でデータ移行

あるコレクションのデータ構造を変更したので既存データを移行しないといけない。mongosh を使うと javascript っぽい文法で repl から mongodb のデータを操作できる。私は sql を書く方が好みだけど、慣れの問題で mongosh はプログラミングに近い形でオブジェクトを操作してデータを更新できる。例えば、history というコレクションを3件だけ取得して1件ずつ dump するコードは次のようになる。

> db.history.find().limit(3).forEach(function(i) {console.log(i)})

なにかしら関数内で処理した結果を用いて更新しないといけないようなときに forEach を使うと簡単にデータ移行できる。しかし、これは1件ずつ更新を実行するので時間はかかる。余談だけど、mongosh をリモートから接続すると forEach で取得するデータをローカルに fetch してくるので document のサイズに比例してデータの取得分の時間だけ遅くなる。forEach を使うときは ssh で mongodb のサーバーにログインして、そこで mongosh を起動した方が効率よくデータ移行できる。

compose 環境の mongodb に direct 接続するときはこんな感じ。

$ docker compose exec -it mongo mongosh "mongodb://${USER}:${PASSWORD}@localhost:27017/?authMechanism=DEFAULT&directConnection=true"

シンプルな条件で更新できるようなときは updateMany を使ってバッチ更新すると1件ずつ更新するよりめちゃくちゃ速い。私の環境では270万件ほど更新するのが数分で完了した。仮想マシン上のコンテナ環境なので実機だったらもっと速いはず。

> db.history.updateMany({type:null}, {$set:{type:"myType"}}, {})