MongoDBを操作する際、シンプルなCRUDであればmongoシェルに入って直接クエリ実行すれば良いですが、aggregateなど複雑なクエリを実行したいときなど、スクリプトを書いて実行したいケースが出てきます。
mongoコマンドにファイルパスを渡して、jsのスクリプトを実行することができます。
find
まずはスクリプトの作成
find.js
// 2021-05-17 00:00:00以降に作成されたユーザーを取得
db.users.find(
{"created_at": {"$gte": ISODate("2021-05-16T15:00:00.000Z")}},
{"name": 1, "email": 1, "created_at": 1}
).forEach(function(user){
// JSONを整形して出力
print(JSON.stringify(user, null, 4));
});
スクリプトの実行
# --quietオプションでDB接続時の出力を非表示
$ mongo <db_name> find.js --quiet
{
"_id": {
"$oid": "6216f5582da21fbad33d315f"
},
"name": "test01",
"email": "test01@example.com",
"created_at": "2022-02-24T03:02:48.503Z"
}
{
"_id": {
"$oid": "6216f5592da21fbad33d3167"
},
"name": "test02",
"email": "test02@example.com",
"created_at": "2022-02-24T03:02:49.146Z"
}
{
"_id": {
"$oid": "6216f5592da21fbad33d3168"
},
"name": "test03",
"email": "test03@example.com",
"created_at": "2022-02-24T03:02:49.218Z"
}
aggregate
aggregateも同様に実行できます。以下ではidとnameをカンマで結合して出力しています。
aggregate.js
// グループに所属していないユーザーを取得
db.users.aggregate([
{
"$lookup": {
"from": "groups",
"localField": "_id",
"foreignField": "users.id",
"as": "groups"
}
},
{"$match": {"groups": {"$size": 0}}}
]).forEach(function(user){
// _idとnameをカンマ区切りで出力
print(user._id + ',' + user.name);
});
# 結果をテキストファイルに出力
$ mongo <db_name> aggregate.js --quiet > result.txt
$ cat result.txt
6216f55f2da21fbad33d31a0,test04
6216f55f2da21fbad33d31a1,test05
6216f55f2da21fbad33d31a9,test08
6216f55f2da21fbad33d31aa,test10
こんな感じで実行することができます。