LoginSignup
2
2

More than 1 year has passed since last update.

MongoDB (例題)

Last updated at Posted at 2022-02-27

目次

  • create, drop collection
  • find
  • strLenCP
  • distinct
  • count
  • index
  • and
  • in, not, nin, regex
  • gt, gte, lt, lte
  • skip, limit
  • unwind
  • project
  • addFields
  • dateToString
  • concatArrays, concat
  • exists
  • cond, if
  • switch
  • where
  • 更新
  • グループ、カウント、SUM、MAX
  • 同じDB内のCollectionの結合
  • 異なるDBのCollectionの更新コマンド]
  • 小さい処理
  • function
  • dump/restore, export/import

当例題は、下記データを元に記載したクエリと実行結果になります。

DB Name : Employee, Collection Name : emp

_id emp_id emp_name emp_class hobby salary delete_flg reflect_flg create_date update_date
ObjectId(....1) 1001 Emp1 100 ["reading", "music"] 1000 0 2021-01-01 ISODate("2021-01-15T02:50:00.304Z")
ObjectId(....2) 1002 Emp2 100 ["writing", "music"] 2000 0 2021-02-01 ISODate("2021-01-15T02:50:00.304Z")
ObjectId(....3) 1003 Emp3 100 ["speaking", "music"] 3000 0 2021-03-01 ISODate("2021-01-15T02:50:00.304Z")
ObjectId(....4) 1004 Emp4 200 ["teaching", "music"] 4000 0 2021-04-01 ISODate("2021-01-15T02:50:00.304Z")
ObjectId(....5) 1005 Emp5 200 ["learning", "music"] 5000 0 null 2021-05-01 ISODate("2021-01-15T02:50:00.304Z")
ObjectId(....6) 1006 Emp6 300 ["reading", "music"] 6000 0 0 2021-06-01 ISODate("2021-01-15T02:50:00.304Z")
ObjectId(....6) 1007 Emp7 300 ["reading"] 1 0 2021-07-01 ISODate("2021-01-15T02:50:00.304Z")
ObjectId(....6) 1008 Emp8 300 ["music"] 8000 0 1 2021-08-01 ISODate("2021-01-15T02:50:00.304Z")

create, drop collection

# Employee DBのempコレックションを作成する
db.getSiblingDB("Employee").createCollection("emp")

# Employee DBのempコレックションを削除する
db.getSiblingDB("Employee").getCollection("emp").drop()

find

# empの全てのドキュメントを抽出する
db.getCollection("emp").find({})

# 全てのempドキュメントのemp_id列のみ抽出する(_idは指定しないとデフォルトで表示される)
# 1:表示、0:非表示
db.getCollection("emp").find({}, {"_id" : 0, "emp_id" : 1})

# emp_id昇順で抽出する
# 1:昇順、-1:降順
db.getCollection(“emp”)
.find({})
.sort({"emp_id" : 1})
.collation({ locale: "jp", numericOrdering: true })
※collation指定は、文字ソートする場合に必要
(ない場合「1, 11, 2, 3」順になる、あう場合「1, 2, 3, 11」順になる)

「null, 値有無」のreflect_flg列の操作結果

# 1. 全てのdocumentの抽出
> db.getCollection('emp').find({}, {"_id" : 0, "emp_id" : 1, "reflect_flg" : 1})
{ "emp_id" : "1001" }
{ "emp_id" : "1002" }
{ "emp_id" : "1003" }
{ "emp_id" : "1004" }
{ "emp_id" : "1005", "reflect_flg" : null }
{ "emp_id" : "1006", "reflect_flg" : "0" }
{ "emp_id" : "1007", "reflect_flg" : "0" }
{ "emp_id" : "1008", "reflect_flg" : "1" }
# 2. reflect_flg存在しない、かつ、null設定のdocumentの抽出
> db.getCollection('emp').find({"reflect_flg" : null}, {"_id" : 0, "emp_id" : 1, "reflect_flg" : 1})
{ "emp_id" : "1001" }
{ "emp_id" : "1002" }
{ "emp_id" : "1003" }
{ "emp_id" : "1004" }
{ "emp_id" : "1005", "reflect_flg" : null }
# 3. reflect_flgの存在しないのdocumentの抽出
> db.getCollection('emp').find({"reflect_flg" : {$exists : false}}, {"_id" : 0, "emp_id" : 1, "reflect_flg" : 1})
{ "emp_id" : "1001" }
{ "emp_id" : "1002" }
{ "emp_id" : "1003" }
{ "emp_id" : "1004" }
# 4. reflect_flgが存在し、null設定のdocumentの抽出
> db.getCollection('emp').find({"reflect_flg" : {$exists : true, $eq : null} }, {"_id" : 0, "emp_id" : 1, "reflect_flg" : 1}) // will be 'and' condition
{ "emp_id" : "1005", "reflect_flg" : null }
# 5. reflect_flgが存在し、null設定ではないdocumentの抽出
> db.getCollection('emp').find({"reflect_flg" : {$ne : null}}, {"_id" : 0, "emp_id" : 1, "reflect_flg" : 1})
> db.getCollection('emp').find({"reflect_flg" : {$exists : true, $ne : null}}, {"_id" : 0, "emp_id" : 1, "reflect_flg" : 1})

{ "emp_id" : "1006", "reflect_flg" : "0" }
{ "emp_id" : "1007", "reflect_flg" : "0" }
{ "emp_id" : "1008", "reflect_flg" : "1" }
# 6. reflect_flgが存在するdocumentの抽出
> db.getCollection('emp').find({"reflect_flg" : {$exists : true}}, {"_id" : 0, "emp_id" : 1, "reflect_flg" : 1})
> db.getCollection('emp').find({"reflect_flg" : null, "reflect_flg" : {$exists : true} }, {"_id" : 0, "emp_id" : 1, "reflect_flg" : 1}) // will be 'or' condition

{ "emp_id" : "1005", "reflect_flg" : null }
{ "emp_id" : "1006", "reflect_flg" : "0" }
{ "emp_id" : "1007", "reflect_flg" : "0" }
{ "emp_id" : "1008", "reflect_flg" : "1" }

strLenCP

# 社員名の文字数が4桁の社員を抽出する
db.getCollection('emp').find({ "$expr": { "$eq": [ { "$strLenCP": "$emp_name" }, 4 ] } },
 { "_id" : 0, "emp_id" : 1, "emp_name" : 1 }) 

>結果
{ "emp_id" : "1001", "emp_name" : "Emp1"}
{ "emp_id" : "1002", "emp_name" : "Emp2"}
{ "emp_id" : "1003", "emp_name" : "Emp3"}
{ "emp_id" : "1004", "emp_name" : "Emp4"}
{ "emp_id" : "1005", "emp_name" : "Emp5"}
{ "emp_id" : "1006", "emp_name" : "Emp6"}
{ "emp_id" : "1007", "emp_name" : "Emp7"}
{ "emp_id" : "1008", "emp_name" : "Emp8"}

distinct

# 重複なしのemp_classを抽出する
db.getCollection("emp").distinct("emp_class")

>結果
[
  “100”,
  “200”,
  “300”
]
# 条件付:削除フラグ=0 中の重複なしのreflect_flgを抽出する
db.getCollection('emp').distinct("reflect_flg", {"delete_flg" : "0"})

>結果
[
    null,
    "0",
    "1"
]
# 重複なしのreflect_flgのサイズを取得する
db.getCollection('emp').distinct("reflect_flg", {"delete_flg" : "0"}).length

>結果
3

count

# emp Collectionの件数を抽出する
Db.getCollection(“emp”).find({}).count()

>結果

8

index

# emp Collectionのemp_idに対して、インデックスを設定する
db..getCollection("emp").createIndex({ emp_id: 1}, { name : "pk_key" })
# 「unique : true」がある場合、「emp_idとemp_name」の重複データが登録出来ないようになる
db..getCollection("emp").createIndex({ emp_id: 1, emp_name: 1 }, { name : "pk_key", unique : true })
# インデックスを設定する
db.getCollection("emp").createIndex({ emp_name: 1}, { name : "empName_index" })
# インデックスを削除する
db.getCollection("emp").dropIndex("empName_index")

and

# 趣味が読書一個のみのempを検索し、emp_id, hobby列のみ表示する
db.getCollection(“emp”).find({
  $and : [
    { "hobby" : "reading" },
    { "hobby" : { $size : 1 } }
  ] 
}, { "_id" : 0, "emp_id" : 1, "hobby" : 1 })

>結果

{ "emp_id" : "1007", "hobby" : [ "reading" ] }

in, not, nin, regex

# $in:趣味が読書、書くのempを抽出する
db.getCollection(“emp”).find(
 { "hobby" : { $in : ["reading", "writing"] } },
 { "_id" : 0, "emp_id" : 1, "hobby" : 1 } )

# 結果
{ "emp_id" : "1001", "hobby" : [ "reading", "music" ] }
{ "emp_id" : "1002", "hobby" : [ "writing", "music" ] }
{ "emp_id" : "1006", "hobby" : [ "reading", "music" ] }
{ "emp_id" : "1007", "hobby" : [ "reading" ] }
# $not, $in:趣味が聞く以外のempを抽出する
db.getCollection(“emp”).find(
 { "hobby" : { $not : { $in : ["music"] } } },
 { "_id" : 0, "emp_id" : 1, "hobby" : 1 })

または

db.getCollection(“emp”).find(
 { "hobby" : { $nin : ["music"] } },
 { "_id" : 0, "emp_id" : 1, "hobby" : 1 })

# 結果
{ "emp_id" : "1007", "hobby" : [ "reading" ] }
# $regex:趣味がmu開始文字以外のempを抽出する
db.getCollection(“emp”).find(
 { "hobby" : { $not : { $regex : /^mu/ } } },
 { "_id" : 0, "emp_id" : 1, "hobby" : 1} )

または

db.getCollection(“emp”).find(
 { "hobby" : { $not : { $in : /^mu/ } } },
 { "_id" : 0, "emp_id" : 1, "hobby" : 1} )


# 結果
{ "emp_id" : "1007", "hobby" : [ "reading" ] }

gt, gte, lt, lte

# 更新日が2021-02-01以降のempを件数を出す
# 結果:0件
db.getCollection(“emp”).find(
{ "update_date" : { $gte : ISODate("2021-02-01") } }
).count()

# 2021-01-01 < 更新日 <= 2021-02-01のempを件数を出す
# 結果:8件
db.getCollection(“emp”).find(
{ "update_date" : { $gt : ISODate("2021-01-01"),
                    $lte : ISODate("2021-02-01") } 
}
).count()

# 更新日< 2021-02-01、かつ、登録日が2021-01-01のempを件数を出す
# 結果:1件
db.getCollection(“emp”).find(
{ "update_date" : { $lt : ISODate("2021-02-01") },
  "create_date" : "2021-01-01" 
}
).count()

skip, limit

# skip, limit指定前の結果
# 趣味が読書と書くのempを抽出する
db.getCollection(“emp”).find(
 { "hobby" : { $in : ["reading", "writing"] } },
 { "_id" : 0, "emp_id" : 1, "hobby" : 1 } )
.sort({"emp_id" : 1})

# 結果
{ "emp_id" : "1001", "hobby" : [ "reading", "music" ] }
{ "emp_id" : "1002", "hobby" : [ "writing", "music" ] }
{ "emp_id" : "1006", "hobby" : [ "reading", "music" ] }
{ "emp_id" : "1007", "hobby" : [ "reading" ] }
# skip, limit指定後の結果
# 趣味が読書と書くのempの中、3番目から1ドキュメントを抽出する
db.getCollection(“emp”).find(
 { "hobby" : { $in : ["reading", "writing"] } },
 { "_id" : 0, "emp_id" : 1, "hobby" : 1 } )
.sort({"emp_id" : 1})
.skip(2)
.limit(1)

# 結果
{ "emp_id" : "1006", "hobby" : [ "reading", "music" ] }

または

db.getCollection(“emp”).find(
 { "hobby" : { $in : ["reading", "writing"] } },
 { "emp_id" : 1, $skip : 2, $limit : 1 } )
# 結果
{ "_id" : ObjectId(....6), "emp_id" : "1006" }

unwind

# emp_id=1001のdocumentを抽出する
db.getCollection('emp').find({"emp_id" : "1001"}, { "_id" : 0, "emp_id" : 1, "hobby" : 1})

# 結果
{ "emp_id" : "1001", "hobby" : ["reading", "music"] }
# emp_id=1001のhobby配列の値ごとにdocumentを抽出する
db.getCollection('emp').aggregate( [ 
  { $match : {"emp_id" : "1001"} },
  { $unwind : "$hobby" },
  { $project : { "_id" : 0, "emp_id" : 1, "hobby" : 1} }
] )

# 結果
{ "emp_id" : "1001", "hobby" : "reading"}
{ "emp_id" : "1001", "hobby" : "music"}

配列中身のデータに該当するデータを出す

arrayObjectTestコレクションに社員に対する質問と回答のデータが存在する
/* 1 */
{
    "_id" : ObjectId("6226c0ee4c62c33e842e4bb0"),
    "questionId" : "1",
    "emp_id" : "1001",
    "questionList" : [ 
        {
            "qId" : "1",
            "questionName" : "好きな食べ物",
            "answerList" : [ 
                {
                    "answerId" : "1",
                    "answerText" : "肉"
                }, 
                {
                    "answerId" : "2",
                    "answerText" : "ケーキ"
                }, 
                {
                    "answerId" : "3",
                    "answerText" : "野菜"
                }
            ],
            "resultText" : ""
        }, 
        {
            "qId" : "2",
            "questionName" : "好きな音楽",
            "answerList" : [ 
                {
                    "answerId" : "1",
                    "answerText" : "POP"
                }, 
                {
                    "answerId" : "2",
                    "answerText" : "R&B"
                }
            ],
            "resultText" : ""
        }
    ],
    "createDate" : ISODate("2022-01-01T01:09:44.542Z")
}
/* 2 */
{
    "_id" : ObjectId("6226c1144c62c33e842e4beb"),
    "questionId" : "2",
    "emp_id" : "1002",
    "questionList" : [ 
        {
            "qId" : "1",
            "questionName" : "好きな食べ物",
            "answerList" : [ 
                {
                    "answerId" : "1",
                    "answerText" : "ケーキ"
                }, 
                {
                    "answerId" : "2",
                    "answerText" : "野菜"
                }
            ],
            "resultText" : ""
        }, 
        {
            "qId" : "2",
            "questionName" : "好きな音楽",
            "answerList" : [ 
                {
                    "answerId" : "1",
                    "answerText" : "POP"
                }
            ],
            "resultText" : ""
        }
    ],
    "createDate" : ISODate("2022-02-01T01:09:44.542Z")
}
# 答えに「ケーキ」がある質問に該当する、questionId, answerIdとanswerTextを出す
db.getCollection('arrayObjectTest').aggregate([
 { "$unwind": "$questionList" }
 , { "$unwind": "$questionList.answerList" }
 , { "$match": { "questionList.answerList.answerText" : "ケーキ" } }
 , { "$addFields": { "answerId": { $concat : ["", "$questionList.answerList.answerId"] },
                     "answerText": { $concat : ["", "$questionList.answerList.answerText"] } } }
 , { "$project" : {"_id":0, "questionId" : 1, "answerId"  : 1, "answerText"  : 1} }
])

## 結果
{ "questionId" : "1", "answerId" : "2", "answerText" : "ケーキ"}
{ "questionId" : "2", "answerId" : "1", "answerText" : "ケーキ"}

project

# insert document
db.getCollection('order_info').insert(
{
    "item_id" : NumberLong(1),
    "stock_info" : ["cloth", "winter"],
    "order_info" : ["men", "kids"]
})

> db.getCollection('order_info').find({})
{
 "_id" : ObjectId("61b1d6ea29182be1a230d25d"),
 "item_id" : NumberLong(1), 
 "stock_info" : ["cloth", "winter"], 
 "order_info" : ["men", "kids"]
}
# item_id項目のみ、出力する
db.getCollection('order_info').aggregate( [ 
  { $project: { "_id" : 0,  "item_id" : 1} }
] )

# 結果
{ "item_id" : 1 }

addFields

# insert document
db.getCollection('order_info').insert(
{
    "item_id" : NumberLong(1),
    "stock_info" : ["cloth", "winter"],
    "order_info" : ["men", "kids"]
})

> db.getCollection('order_info').find({})
{
 "_id" : ObjectId("61b1d6ea29182be1a230d25d"),
 "item_id" : NumberLong(1), 
 "stock_info" : ["cloth", "winter"], 
 "order_info" : ["men", "kids"]
}
# item_id項目のみ、出力する
db.getCollection('order_info').aggregate( [ 
  { $addFields: { "new_column": "Test" } }
] )

# 結果
{
    "_id" : ObjectId("61b1d6ea29182be1a230d25d"),
    "item_id" : NumberLong(1), 
    "stock_info" : ["cloth", "winter"], 
    "order_info" : ["men", "kids"],
    "new_column" : "Test"
}

dateToString

db.getCollection('emp').aggregate(
[ {"$addFields": { update_date2: { $dateToString : { format: "%Y年%m月%d日 %H:%M:%S.%L", date: "$update_date" } } } },
  {"$project" : { "_id" : 0, "emp_id" : 1, "update_date" : 1, "update_date2" : 1 } }
])

>結果
{"emp_id" : "1001", "update_date" : ISODate("2021-01-15T02:50:00.304Z"), "update_date2" : "2021年01月15日 02:50:00.304"}
{"emp_id" : "1002", "update_date" : ISODate("2021-01-15T02:50:00.304Z"), "update_date2" : "2021年01月15日 02:50:00.304"}
{"emp_id" : "1003", "update_date" : ISODate("2021-01-15T02:50:00.304Z"), "update_date2" : "2021年01月15日 02:50:00.304"}
{"emp_id" : "1004", "update_date" : ISODate("2021-01-15T02:50:00.304Z"), "update_date2" : "2021年01月15日 02:50:00.304"}
{"emp_id" : "1005", "update_date" : ISODate("2021-01-15T02:50:00.304Z"), "update_date2" : "2021年01月15日 02:50:00.304"}
{"emp_id" : "1006", "update_date" : ISODate("2021-01-15T02:50:00.304Z"), "update_date2" : "2021年01月15日 02:50:00.304"}
{"emp_id" : "1007", "update_date" : ISODate("2021-01-15T02:50:00.304Z"), "update_date2" : "2021年01月15日 02:50:00.304"}
{"emp_id" : "1008", "update_date" : ISODate("2021-01-15T02:50:00.304Z"), "update_date2" : "2021年01月15日 02:50:00.304"}

concatArrays, concat

# insert document
db.getCollection('order_info').insertMany([
{
    "item_id" : NumberLong(1),
    "stock_info" : ["cloth", "winter"],
    "order_info" : ["men", "kids"]
},
{
    "item_id" : NumberLong(2),
    "item_name" : "spring",
    "item_type" : "cloth",
    "stock_info" : ["cloth", "spring"],
    "order_info" : ["men", "kids"]
}])
# 配列(stock_info, order_info)の値を繋ぐする、かつ、item_nameとitem_typeの文字列を繋ぐ
db.getCollection('order_info').aggregate( [
  { $project: { "_id" : 0,
                "concatArrays" : { $concatArrays: [ "$stock_info", "$order_info" ] },
                "concat" : { $concat: [ "$item_name", " - ", "$item_type" ] }
    } 
  }
] )

# 結果
{ "concatArrays" : [ cloth", "winter", "men", "kids"], "concat" : null }
{ "concatArrays" : [ cloth", "spring", "men", "kids"], "concat" : "concat" : "spring- cloth" }

exists

# reflect_flg列が存在し、「1」に該当するempを抽出する
db.getCollection('emp').find({"reflect_flg" : {$exists : true, $eq : "1"}} // can also add for type (eg. name : { $exists: true, $not: { $type: "array" }, $type: "object" })
, {"_id" : 0, "emp_id" : 1, "reflect_flg" : 1 })

> 結果
{
    "emp_id" : "1008",
    "reflect_flg" : "1"
}

cond, if

# emp_class=100の場合は「100 class」を出力する。それ以外は「Other class」をを出力する。
db.getCollection('emp').aggregate([
  { "$addFields": { "condition_result" : 
                         {$cond: {if: { $eq: [ "$emp_class", "100" ] }, 
                                    then: "100 class",
                                  else: 
                                    "Other class" }}}
  },
  {"$project" : {"_id" : 0, "emp_id": 1, "emp_class" : 1, "condition_result" : 1}}
])

または

db.getCollection('emp').aggregate([
  { "$addFields": { "condition_result" : 
                         {$cond: [ { $eq: [ "$emp_class", "100" ] },
                                   "100 class",
                                   "Other class" 
                                 ]}}
  },
  {"$project" : {"_id" : 0, "emp_id": 1, "emp_class" : 1, "condition_result" : 1}}
])

または

db.getCollection('emp').aggregate([
  {"$project" : {"_id" : 0, "emp_id": 1, "emp_class" : 1,
                 "condition_result" : {$cond: [ { $eq: [ "$emp_class", "100" ] },
                                               "100 class",
                                               "Other class" 
                                       ]}
              }
   }
])
>結果
{ "emp_id" : "1001", "emp_class" : "100", "condition_result" : "100 class" }
{ "emp_id" : "1002", "emp_class" : "100", "condition_result" : "100 class" }
{ "emp_id" : "1003", "emp_class" : "100", "condition_result" : "100 class" }
{ "emp_id" : "1004", "emp_class" : "200", "condition_result" : "Other class" }
{ "emp_id" : "1005", "emp_class" : "200", "condition_result" : "Other class" }
{ "emp_id" : "1006", "emp_class" : "300", "condition_result" : "Other class" }
{ "emp_id" : "1007", "emp_class" : "300", "condition_result" : "Other class" }
{ "emp_id" : "1008", "emp_class" : "300", "condition_result" : "Other class" }

switch

# insert data
db.getCollection('grade_info').insertMany([
{ "name" : "Susan Wilkes", "scores" : [ 87, 86, 78 ] },
{ "name" : "Bob Hanna", "scores" : [ 71, 64, 81 ] },
{ "name" : "James Torrelio", "scores" : [ 91, 84, 97 ] }
])
# scoresの平均(x)の下記を出力する
#  ・x <= 40は、low scroes
#  ・40 < x <= 80は、medium scroes
#  ・その他は、hight scroes
db.getCollection('grade_info').aggregate([
  {"$project" : {"_id" : 0, "name": 1, "scores" : 1,
                 "average_salary" : {$avg : "$scores"},
                 "condition_result" : {
                    $switch: {
                       branches: [
                         { case: { $lte : [ { $avg : "$scores" }, 40 ] }, then: "low scores" },
                         { case: { $and : [ { $gt : [ { $avg : "$scores" }, 40 ] },
                                            { $lte  : [ { $avg : "$scores" }, 80 ] } ] }, then: "medium scores" }
                                           ],
                         default: "hight scores"
                      }
                 }
   }}
])

>結果
{ "name" : "Susan Wilkes", "scores" : [ 87, 86, 78 ], "average_salary" : 83.6666666666667, "condition_result" : "hight scores" },
{ "name" : "Bob Hanna", "scores" : [ 71, 64, 81 ], "average_salary" : 72.0, "condition_result" : "medium scores" },
{ "name" : "James Torrelio", "scores" : [ 91, 84, 97 ], "average_salary" : 90.6666666666667, "condition_result" : "hight scores" }

where

# データ確認
> db.getCollection('emp').find({}, {"_id" : 0, "emp_id" : 1, "hobby" : 1})
{ "emp_id" : "1001", "hobby" : [ "reading", "music" ] }
{ "emp_id" : "1002", "hobby" : [ "writing", "music" ] }
{ "emp_id" : "1003", "hobby" : [ "speaking", "music" ] }
{ "emp_id" : "1004", "hobby" : [ "teaching", "music" ] }
{ "emp_id" : "1005", "hobby" : [ "learning", "music" ] }
{ "emp_id" : "1006", "hobby" : [ "reading", "music" ] }
{ "emp_id" : "1007", "hobby" : [ "reading" ] }
{ "emp_id" : "1008", "hobby" : [ "music" ] }
# 趣味が1個より多いempを抽出する
db.getCollection('emp').find({ $where: "this.hobby.length > 1" },
{ "emp_id" : "1001", "hobby" : [ "reading", "music" ] }
{ "emp_id" : "1002", "hobby" : [ "writing", "music" ] }
{ "emp_id" : "1003", "hobby" : [ "speaking", "music" ] }
{ "emp_id" : "1004", "hobby" : [ "teaching", "music" ] }
{ "emp_id" : "1005", "hobby" : [ "learning", "music" ] }
{ "emp_id" : "1006", "hobby" : [ "reading", "music" ] }

更新

####例①:emp_class="100"に対して、reflect_flg="0"を設定する

# emp_class="100"に対して、reflect_flg="0"を設定する
db.getCollection("emp").update(
 { "emp_class" : "100" },             // 更新条件
 { $set : { "reflect_flg" : "0" } },  // 更新データ
 { multi : true }             // 複数行の更新指定
)

# emp_id, emp_class, reflect_flg列のみ表示し、全ての行を抽出しする
db.getCollection("emp").find({}, { "_id" : 0, "emp_id" : 1, "emp_class" : 1, "reflect_flg" : 1 })

>結果
{ "emp_id" : "1001", "emp_class" : "100", "reflect_flg" : "0"}
{ "emp_id" : "1002", "emp_class" : "100", "reflect_flg" : "0"}
{ "emp_id" : "1003", "emp_class" : "100", "reflect_flg" : "0"}
{ "emp_id" : "1004", "emp_class" : "200"}
{ "emp_id" : "1005", "emp_class" : "200", "reflect_flg" : null}
{ "emp_id" : "1006", "emp_class" : "300", "reflect_flg" : "0"}
{ "emp_id" : "1007", "emp_class" : "300", "reflect_flg" : "0"}
{ "emp_id" : "1008", "emp_class" : "300", "reflect_flg" : "1"}

グループ、カウント、SUM、MAX

例①:1項目のグループ

db.getCollection("emp").aggregate([
  {
    "$group" : { _id : "$emp_class" } // group can also for object field (eg. $details.Name")
  }])

>結果
{ "_id" : "100"}
{ "_id" : "200"}
{ "_id" : "300"}

###例②:カウント

emp_classでグループした結果を出す

# skip, limit無し:全てのdocumentを出す
db.getCollection("emp").aggregate([
  {
    $group :
     {
    _id : "$emp_class",
      total : { $sum : 1 }
   }
  }, 
  {"$sort"  : {"total" : 1} }
])

>結果
{ "_id" : "200", "total" : 2.0 }
{ "_id" : "300", "total" : 3.0 }
{ "_id" : "100", "total" : 3.0 }
## skip, limit有り:2行目から5件出す
db.getCollection("emp").aggregate([
  {
    $group :
     {
    _id : "$emp_class",
      total : { $sum : 1 }
   }
  }, 
  {"$sort"  : {"total" : 1} },
  {"$skip"  : 1 },
  {"$limit" : 5 }
])

>結果
{ "_id" : "300", "total" : 3.0 }
{ "_id" : "100", "total" : 3.0 }

delete_flgが0に該当するdocumentから、emp_classでグループし、件数を出す

db.getCollection('emp').aggregate(
  [ {$match: {"delete_flg" : "0"} }, // can write many $match
    {$group: {"_id" : "$emp_class"} },
    {$count: "count"  }
  ])

>結果
3

####例③:複数項目のグループ

db.getCollection("emp").aggregate([
  {
    $group :
     {
    _id : 
       {
         "class" : "$emp_class",
         "reflectFlg" : "$reflect_flg"
      },
      total : { $sum : 1 }
   }
  }
])

>結果
{ "_id" : { "class" : "100" },  "total" : 3.0 }
{ "_id" : { "class" : "200" },  "total" : 1.0 }
{ "_id" : { "class" : "200", "reflectFlg" : null },  "total" : 1.0 }
{ "_id" : { "class" : "300", "reflectFlg" : "0" },  "total" : 2.0 }
{ "_id" : { "class" : "300", "reflectFlg" : "1" },  "total" : 1.0 }

####例④:条件付きグループ

db.getCollection("emp").aggregate([
  { $match : { "delete_flg" : "0" } },
  {
    $group :
     {
    _id : 
       {
         "class" : "$emp_class",
         "reflectFlg" : "$reflect_flg"
      },
      total : { $sum : 1 }
   }
  }
])

>結果
{ "_id" : { "class" : "100" },  "total" : 3 }
{ "_id" : { "class" : "200" },  "total" : 1 }
{ "_id" : { "class" : "200", "reflectFlg" : null },  "total" : 1 }
{ "_id" : { "class" : "300", "reflectFlg" : "0" },  "total" : 1 }
{ "_id" : { "class" : "300", "reflectFlg" : "1" },  "total" : 1 }

####例⑤:max

db.getCollection("emp").aggregate([
  {
    $group :
     {
    _id : 
       {
         "class" : "$emp_class",
         "reflectFlg" : "$reflect_flg"
      },
      total : { $sum : 1 },
      maxDate: { $max : "$create_date" }
   }
  }
])

>結果
{ "_id" : { "class" : "100" },  "total" : 3, "maxDate" : "2021-03-01" }
{ "_id" : { "class" : "200" },  "total" : 1, "maxDate" : "2021-04-01" }
{ "_id" : { "class" : "200", "reflectFlg" : null },  "total" : 1, "maxDate" : "2021-05-01" }
{ "_id" : { "class" : "300", "reflectFlg" : "0" },  "total" : 2, "maxDate" : "2021-07-01" }
{ "_id" : { "class" : "300", "reflectFlg" : "1" },  "total" : 1, "maxDate" : "2021-08-01" }

####例⑥:ソート(maxDate降順)

db.getCollection("emp").aggregate([
  {
    $group :
     {
    _id : 
       {
         "class" : "$emp_class",
         "reflectFlg" : "$reflect_flg"
      },
      total : { $sum : 1 },
      maxDate: { $max : "$create_date" }
   }
  },
  { $sort : { "maxDate" : -1 } },
  //{ $skip : 1 },
  //{ $limit : 2 },
])

>結果
{ "_id" : { "class" : "300", "reflectFlg" : "1" },  "total" : 1, "maxDate" : "2021-08-01" }
{ "_id" : { "class" : "300", "reflectFlg" : "0" },  "total" : 2, "maxDate" : "2021-07-01" }
{ "_id" : { "class" : "200", "reflectFlg" : null },  "total" : 1, "maxDate" : "2021-05-01" }
{ "_id" : { "class" : "200" },  "total" : 1, "maxDate" : "2021-04-01" }
{ "_id" : { "class" : "100" },  "total" : 3, "maxDate" : "2021-03-01" }

####例⑦:全てのempの給料を足す

db.getCollection('emp').aggregate(
[{ $group: {
      _id: {},
     "total": {"$sum": "$salary"}} }
])

>結果
{
    "_id" : {},
    "total" : NumberLong(29000)
}

####例⑧:新規フィールド(合計salary, strConcat = emp_name + " : " + emp_class)の追加

db.getCollection('emp').aggregate(
[ { $addFields : {
      "strConcat": {"$concat": [ "$emp_name", " : ","$emp_class" ] },
      "total": { $sum: [ "$salary"] }
   }},
   { $project : {"_id" : 0, "emp_id" : 1, "salary" : 1, "strConcat" : 1, "total" : 1} } // 出力フィールドの指定
])

>結果
{ "emp_id" : "1001", "salary" : NumberLong(1000), "strConcat" : "Emp1 : 100", "total" : NumberLong(1000) }
{ "emp_id" : "1002", "salary" : NumberLong(2000), "strConcat" : "Emp2 : 100", "total" : NumberLong(2000) }
{ "emp_id" : "1003", "salary" : NumberLong(3000), "strConcat" : "Emp3 : 100", "total" : NumberLong(3000) }
{ "emp_id" : "1004", "salary" : NumberLong(4000), "strConcat" : "Emp4 : 200", "total" : NumberLong(4000) }
{ "emp_id" : "1005", "salary" : NumberLong(5000), "strConcat" : "Emp5 : 200", "total" : NumberLong(5000) }
{ "emp_id" : "1006", "salary" : NumberLong(6000), "strConcat" : "Emp6 : 300", "total" : NumberLong(6000) }
{ "emp_id" : "1007", "strConcat" : "Emp7 : 300", "total" : NumberLong(0) }
{ "emp_id" : "1008", "salary" : NumberLong(2000), "strConcat" : "Emp8 : 300", "total" : NumberLong(8000) }

同じDB内のCollectionの結合

# Employee DB内、emp_experience Collectionを作り、データ挿入する
db.getCollection('emp_experience').insertMany([
{
    "emp_id" : "1001",
    "experience" : ["Java"],
    "update_date" : ISODate("2020-12-31T09:00:00.000Z")
},
{
    "emp_id" : "1001",
    "experience" : ["Java", "PHP"],
    "update_date" : ISODate("2021-01-31T09:00:00.000Z")
},
{
    "emp_id" : "1002",
    "experience" : ["Python"],
    "update_date" : ISODate("2021-02-28T09:00:00.000Z")
},
{
    "emp_id" : "1003",
    "experience" : ["Java"],
    "update_date" : ISODate("2021-03-31T09:00:00.000Z")
}
])

emp, emp_experience Collectionを結合した件数を出す

db.getCollection('emp_experience').aggregate(
[
  { $lookup : {
          from : "emp",
          let  : { exp_emp_id : "$emp_id" }, // emp_experience collection's emp_id
          pipeline : [
           { $match : {
                 $expr : {
                   $and : [ { $eq : [ "$emp_id", "$$exp_emp_id"] } ]
              } }
           }
         ],
         as : "emp"
      }      
  },
  {
   "$unwind": {"path": "$emp",
               "preserveNullAndEmptyArrays": false // true : will also print for not exist (field/ left join), false : inner join
  }},
  { $group: { _id: null, total: { $sum: 1 } } },
])
# 結果
{
    "_id" : null,
    "total" : 4.0
}

emp, emp_experience Collectionを結合し、emp_idでグループした件数を出す

db.getCollection('emp_experience').aggregate(
[
  { $lookup : {
          from : "emp",
          let  : { exp_emp_id : "$emp_id" }, // emp_experience collection's emp_id
          pipeline : [
           { $match : {
                 $expr : {
                   $and : [ { $eq : [ "$emp_id", "$$exp_emp_id"] } ]
              } }
           }
         ],
         as : "emp"
      }      
  },
  {
   "$unwind": {"path": "$emp",
               "preserveNullAndEmptyArrays": false // true : will also print for not exist (field/ left join), false : inner join
  }},
  { $group: { _id: { "emp_id" : "$emp_id"}, total: { $sum: 1 } } },
])
# 結果
{ "_id" : {"emp_id" : "1003" }, "total" : 1.0 }
{ "_id" : {"emp_id" : "1001" }, "total" : 2.0 }
{ "_id" : {"emp_id" : "1002" }, "total" : 1.0 }

emp_experienceの更新日「2021-01-01」後のデータとempを結合した結果

db.getCollection('emp_experience').aggregate(
[
  { $match : { "update_date" : { $gt : ISODate("2021-01-01T09:00:00.000Z") } } },
  { $lookup : {
          from : "emp",
          let  : { exp_emp_id : "$emp_id" }, // emp_experience collection's emp_id
          pipeline : [
           { $match : {
                 $expr : {
                   $and : [ { $eq : [ "$emp_id", "$$exp_emp_id"] } ]
              } }
           }
         ],
         as : "emp"
      }      
  },
  {
   "$unwind": {"path": "$emp",
               "preserveNullAndEmptyArrays": false // true : will also print for not exist (field/ left join), false : inner join
  }},
  { "$project": {"_id" : 0, "emp_id" : 1, "experience" : 1 } }
 // { $group: { _id: null, total: { $sum: 1 } } },
])
# 結果
{ "emp_id" : "1001", "experience" : ["Java", "PHP"] }
{ "emp_id" : "1002", "experience" : ["Python"] }
{ "emp_id" : "1003", "experience" : ["Java"] }

empとemp_experienceを結合し、「"emp_id" : "1001"」に該当するデータの全件と最初の10件を出す

前提:emp_experienceに「"emp_id" : "1001"」のデータが30件存在とする。
db.getCollection('emp_experience').aggregate([
{"$match": {"$and": [{"emp_id": "1001"}] } },
{ "$facet" :{ 
    "metadata" :[{"$count": "total"}],
    "data" :[
      {"$lookup": {
                    "from": "emp", 
                    "let": {"emp_id": "$emp_id"}, 
                    "pipeline": [{"$match": {"$expr": {"$eq": ["$emp_id", "$$emp_id"]} } },
                                 { "$limit" :1 } ],
                    "as" :"document" } },
    {
      "$unwind" :{ 
        "path" :"$document",
        "preserveNullAndEmptyArrays" :false
      } },
    { "$sort" :{ "emp_id" :- 1 } },
    { "$skip" :0 },
    { "$limit" :10 }
   ]
  }
} ])
# 結果
{
    "metadata" : [{ "total" : 30 }],
    "data" : [  // 下記と同様の結合した最初の10件が出てくる
        { "_id" : ....,
          "emp_id" : "1001",
          "experience" : ....,
          "update_date" : ....,
          "document" : { // emp Collection's data
                         "_id" : ....,
                         "emp_id" : "1001",
                         "emp_name" : ....,
                         ...
                       }
        },
        ...
    ]
}

異なるDBのCollectionの更新コマンド

DB Name : EmployeeJob, Collection Name : emp_job

_id emp_id emp_job_id delete_flg create_date
ObjectId(....1) 1001 100 0 2021-01-01
ObjectId(....2) 1002 100 0 2021-02-01
ObjectId(....3) 1003 100 0 2021-03-01
ObjectId(....4) 1004 200 0 2021-04-01
ObjectId(....5) 1005 200 0 2021-05-01
ObjectId(....6) 1006 300 0 2021-06-01
ObjectId(....6) 1007 300 0 2021-07-01
ObjectId(....6) 1008 300 0 2021-08-01

1.下記コマンドの内容の説明
Employee DBのemp Collectionの各データに対して、EmployeeJob DBのemp_job Collectionの下記列のデータを変更する。
「emp_job_id=100」の場合、「emp_job_id=1000」に変更
「emp_job_id=200」の場合、「emp_job_id=2000」に変更
「emp_job_id=300」の場合、「emp_job_id=3000」に変更

// emp Collectionの各行に対して、ループする
db.getSiblingDB(“Employee”)
 .getCollection(“emp”)
 .find({})
 .forEach(function(row) {

 // emp_job_idにより、変更値を準備する
 var class = “”;
  if (row.emp_job_id == “100”) {
    class = “1000”;
  } else if (row.emp_job_id == “200”) {
    class = “2000”;
  } else if (row.emp_job_id == “300”) {
    class = “3000”;
  }

 // ログ出す
 print(“Update Data :emp_id=” + row.emp_id + “, class=” + class);

  // 更新処理
 db.getSiblingDB(“EmployeeJob”)
  .getCollection(“emp_job”)
  .update({“emp_id” : row.emp_id},
       {“emp_job_id” : class});

})

// emp_id, emp_job_id列のみ表示し、全ての行を抽出しする
db.getCollection("emp_job").find({}, { "_id" : 0, "emp_id" : 1, "emp_job_id" : 1})

>結果

{ "emp_id" : "1001", "emp_job_id" : "1000"}
{ "emp_id" : "1002", "emp_job_id" : "1000"}
{ "emp_id" : "1003", "emp_job_id" : "1000"}
{ "emp_id" : "1004", "emp_job_id" : "2000"}
{ "emp_id" : "1005", "emp_job_id" : "2000"}
{ "emp_id" : "1006", "emp_job_id" : "3000"}
{ "emp_id" : "1007", "emp_job_id" : "3000"}
{ "emp_id" : "1008", "emp_job_id" : "3000"}

2.下記コマンドの内容の説明
Employee DBのempから3つのdocumentのemp_idを抽出する

db.emp.find().limit(3).forEach(doc => { 
    print(doc.emp_id);
 }
)

# 結果
1001
1002
1003

3.下記コマンドの内容の説明
EmployeeJob DBのemp_jobの3つのemp_idに対して、Employee DBのempから抽出する

db.getSiblingDB("Employee").getCollection("emp").find({"emp_id": 
{ $in: db.getSiblingDB("EmployeeJob").getCollection("emp_job").find().limit(3).map(doc => doc.emp_id) }
}, {"_id" : 0, "emp_id" : 1, "emp_name" : 1} )

小さい処理

「"hobby" : "reading"」に該当するemp_idを変数に格納する
var empIds = [];
db.getCollection('emp').find({"hobby" : "reading"}).forEach(function(emp){
   empIds.push("\"" + emp.emp_id + "\"");
});
for (var i = 0; i < empIds.length; i++) {
    print(empIds[i]);
}
print(empIds.length);
print(empIds.join(","));
# print(empIds[i])の結果
"1001"
"1006"
"1007"
# print(empIds.length)の結果
3
# print(empIds.join(","))の結果
"1001","1006","1007"

function

functionの作成

  • 引数のemp_classに紐づくクラス名を取得する関数を作成する
> db.system.js.save({_id:'getEmpClassName', value:function (paramEmpClass) {
   var result = "";
   switch (paramEmpClass) {
     case "100" : result = "100Name"; break;
     case "200" : result = "200Name"; break;
     case "300" : result = "300Name"; break;
     default : result = "unknow";
   }
   return result;
   }
 });

登録functionの削除

db.system.js.remove({_id:'functionName'})

登録function一覧の取得

> db.getCollection('system.js').find({})
{
    "_id" : "getEmpClassName",
    "value" : function (paramEmpClass) {
                 var result = "";
                 switch (paramEmpClass) {
                   case "100" : result = "100Name"; break;
                   case "200" : result = "200Name"; break;
                   case "300" : result = "300Name"; break;
                   default : result = "unknow";
                 }
                 return result;
     }
}

functionの呼び出し

  • 引数のemp_classに紐づくクラス名を取得する関数を作成する
> db.loadServerScripts()
> getEmpClassName("100")
100Name

> getEmpClassName("200")
200Name

> getEmpClassName("300")
300Name

> getEmpClassName("400")
unknow

異なるDBのCollectionを元に、emp_idに紐づくemp_job_idを取得するfunction

# functionの作成
db.system.js.save({_id:'getJobId', value:function (paramEmpId) {
    db.getSiblingDB("Employee").getCollection("emp").find({"emp_id" : (paramEmpId) }).forEach(function(employee){
      db.getSiblingDB("EmployeeJob").getCollection("emp_job").find({"emp_id" : employee.emp_id }).forEach(function(employeeJob){
           print("\"emp_job_id\" : " + employeeJob.emp_job_id);
      });
    });
  }
});

# 実行結果
> db.loadServerScripts()
> getJobId("1001")
"emp_job_id" : 100

dump/restore, export/import

# デフォルトbsonファイルのエクスポート
mongodump --host=localhost --port=27017 --db=dbName --out=C:\outputFolder

mongorestore --host=localhost --port=27017 --db=dbName C:\inputFolder\collectionName.bson
# ファイルタイプ指定して、エクスポートすることが可能
# csvまたはjsonファイルが出力可能(csvの場合は「--fields or --fieldFile」で出力対象フィールドを指定しなければならない)※

# 条件なしで、コレクションの全てのデータをエクスポートする
mongoexport --db=Employee -c=emp --limit=4 --fields=emp_id,emp_name --type=csv --out=C:\xxxxx\filename.csv

# windows>条件付きでエクスポートする
mongoexport --db=Employee -c=emp --query="{ \"delete_flg\": \"0\" }" --limit=4 --fields=emp_id,emp_name --type=csv --out=C:\xxxxx\filename.csv

# linux>条件付きでエクスポートする
mongoexport --db=Employee -c=emp --query='{"delete_flg":"0"}' --fields=enqueteName --type=csv --out=/tmp/xxx/filename.csv

# windows>csvファイルのデータをインポートする
mongoimport --db=Employee -c=emp --fields=emp_id,emp_name,emp_class --type=csv --file=C:\xxxx\empData.csv

# linux>csvファイルのデータをインポートする
mongoimport --db=Employee -c=emp --fields=emp_id,emp_name,emp_class --type=csv --file=/tmp/empData.csv

※オプションの詳しい説明はこちらを参照してください

2
2
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
2
2