ながれ
1.INSERT
2.UPDATE
3.複数件のUPDATE(update, multi)
4.UPDATE or INSERT的な1(update, upsert)
5.UPDATE or INSERT的な2(save)
6.NOUPDATE or INSERT的な(update, $setOnInsert, upsert)
1.INSERT
基本構文
db.コレクション名.insert({ドキュメントデータ});
ためし
余計なこともしてみますがinsert。
※無いcollectionを指定 -> 特に何も表示されない >db.testcol.find() ※findしただけではcollectionはできない >show collections system.indexes system.users ※まだないcollectionを指定してinsert >db.test.insert({"_id": "a00001", "user_info" : {"name": "hoge", "age": 10}, "user_prof" : {"work": 0, "smorker": 0 } }) >db.test.insert({"_id": "a00002", "user_info" : {"name": "fuga", "age": 21}, "user_prof" : {"work": 1, "smorker": 0 } }) >db.test.insert({"_id": "a00003", "user_info" : {"name": "piyo", "age": 33}, "user_prof" : {"work": 1, "smorker": 1 } }) >db.test.insert({"_id": "a00004", "user_info" : {"name": "waru", "age": 40}, "user_prof" : {"work": 0, "smorker": 1 } }) ※collectionごと作成される >show collections system.indexes system.users test ※すでにあるkeyをinsertしてみる >db.test.insert({"_id": "a00001", "user_info" : {"name": "hoge", "age": 10}, "user_prof" : {"work": 0, "smorker": 0 } }) E11000 duplicate key error index: testdb.test.$_id_ dup key: { : "a00001" }
insertについてはほんとにそのままですね
2.UPDATE
基本のupdateから
基本構文
db.コレクション名.update({条件}, { $set: {更新するドキュメントデータ} });
ためし
※存在しないkeyでupdateしてみる -> 特に何も怒られないがfindしてみると追加はされてない >db.test.update({"_id": "a00005"}, {$set: {"user_info" : {"name": "waru", "age": 40}, "user_prof" : {"work": 0, "smorker": 1 }}}) >db.test.find() { "_id" : "a00001", "user_info" : { "name" : "hoge", "age" : 10 }, "user_prof" : { "work" : 0, "smorker" : 0 } } { "_id" : "a00002", "user_info" : { "name" : "fuga", "age" : 21 }, "user_prof" : { "work" : 1, "smorker" : 0 } } { "_id" : "a00003", "user_info" : { "name" : "piyo", "age" : 33 }, "user_prof" : { "work" : 1, "smorker" : 1 } } { "_id" : "a00004", "user_info" : { "name" : "waru", "age" : 40 }, "user_prof" : { "work" : 0, "smorker" : 1 } } ※a00001のuser_infoのageをupdateしてみる >db.test.update({"_id": "a00001"}, {$set:{"user_info.age": 18}}) >db.test.find({"_id": "a00001"}) { "_id" : "a00001", "user_info" : { "name" : "hoge", "age" : 18 }, "user_prof" : { "work" : 0, "smorker" : 0 } } ※a00001のuser_profをまるっとupdateしてみる >db.test.update({"_id": "a00001"}, {$set:{"user_prof": { "baka" : 0, "aho" : 0 }}}) >db.test.find({"_id": "a00001"}) { "_id" : "a00001", "user_info" : { "name" : "hoge", "age" : 18 }, "user_prof" : { "baka" : 0, "aho" : 0 } } ※一応戻す >db.test.update({"_id": "a00001"}, {$set:{"user_prof": { "work" : 0, "smorker" : 0 }}})
まぁこれも普通な感じですね
複数件のUPDATE(update, multi)
複数件のupdateです。
mysqlとかだとwhere句で指定したものすべてって感じですが、mongoではあえて指定しないとダメなようです
基本構文
db.コレクション名.update({条件}, { $set: {更新するドキュメントデータ} }, {multi: true});
ためし
※特に指定なしでsmorkerが0の人をsmorker=>2にしてみる >db.test.update({"user_prof.smorker": 0}, {$set: {"user_prof.smorker" : 2}}) ※全部表示してみる -> 最初にmatchした1件しか更新されない >db.test.find() { "_id" : "a00001", "user_info" : { "name" : "hoge", "age" : 18 }, "user_prof" : { "work" : 0, "smorker" : 2 } } { "_id" : "a00002", "user_info" : { "name" : "fuga", "age" : 21 }, "user_prof" : { "work" : 1, "smorker" : 0 } } { "_id" : "a00003", "user_info" : { "name" : "piyo", "age" : 33 }, "user_prof" : { "work" : 1, "smorker" : 1 } } { "_id" : "a00004", "user_info" : { "name" : "waru", "age" : 40 }, "user_prof" : { "work" : 0, "smorker" : 1 } } ※いったん戻してからmulti=>falseを指定してsmorker=>2にしてみる >db.test.update({"_id": "a00001"}, {$set:{"user_prof": { "work" : 0, "smorker" : 0 }}}) >db.test.update({"user_prof.smorker": 0}, {$set: {"user_prof.smorker" : 2}}, {multi: false}) ※表示 -> 1件のみupdateされてる >db.test.find() { "_id" : "a00001", "user_info" : { "name" : "hoge", "age" : 18 }, "user_prof" : { "work" : 0, "smorker" : 2 } } { "_id" : "a00002", "user_info" : { "name" : "fuga", "age" : 21 }, "user_prof" : { "work" : 1, "smorker" : 0 } } { "_id" : "a00003", "user_info" : { "name" : "piyo", "age" : 33 }, "user_prof" : { "work" : 1, "smorker" : 1 } } { "_id" : "a00004", "user_info" : { "name" : "waru", "age" : 40 }, "user_prof" : { "work" : 0, "smorker" : 1 } } ※再度いったん戻してからmulti=>trueを指定してsmorker=>2にしてみる >db.test.update({"_id": "a00001"}, {$set:{"user_prof": { "work" : 0, "smorker" : 0 }}}) >db.test.update({"user_prof.smorker": 0}, {$set: {"user_prof.smorker" : 2}}, {multi: true}) ※表示 -> 2件updateされてる >db.test.find() { "_id" : "a00001", "user_info" : { "name" : "hoge", "age" : 18 }, "user_prof" : { "work" : 0, "smorker" : 2 } } { "_id" : "a00002", "user_info" : { "name" : "fuga", "age" : 21 }, "user_prof" : { "work" : 1, "smorker" : 2 } } { "_id" : "a00003", "user_info" : { "name" : "piyo", "age" : 33 }, "user_prof" : { "work" : 1, "smorker" : 1 } } { "_id" : "a00004", "user_info" : { "name" : "waru", "age" : 40 }, "user_prof" : { "work" : 0, "smorker" : 1 } } ※いったん戻す >db.test.update({"_id": "a00001"}, {$set:{"user_prof": { "work" : 0, "smorker" : 0 }}}) >db.test.update({"_id": "a00002"}, {$set:{"user_prof": { "work" : 1, "smorker" : 0 }}})
4.UPDATE or INSERT的な1(update, upsert)
2.UPDATEでやった存在しないkeyでのupdateをやってみます
基本構文
db.コレクション名.update({条件}, { $set: {更新するドキュメントデータ} }, {upsert: true});
ためし
※存在しないkeyでupdateしてみる >db.test.update({"_id": "a00005"}, {$set: {"user_info" : {"name": "waru", "age": 40}, "user_prof" : {"work": 0, "smorker": 1 }}}, { upsert: true }) ※表示 -> a00005が追加されてる >db.test.find() { "_id" : "a00001", "user_info" : { "name" : "hoge", "age" : 18 }, "user_prof" : { "work" : 0, "smorker" : 0 } } { "_id" : "a00002", "user_info" : { "name" : "fuga", "age" : 21 }, "user_prof" : { "work" : 1, "smorker" : 0 } } { "_id" : "a00003", "user_info" : { "name" : "piyo", "age" : 33 }, "user_prof" : { "work" : 1, "smorker" : 1 } } { "_id" : "a00004", "user_info" : { "name" : "waru", "age" : 40 }, "user_prof" : { "work" : 0, "smorker" : 1 } } { "_id" : "a00005", "user_info" : { "name" : "waru", "age" : 40 }, "user_prof" : { "work" : 0, "smorker" : 1 } }
5.UPDATE or INSERT的な2(save)
4.UPDATE or INSERT的な1と似てますかね。
基本構文
db.コレクション名.save({ドキュメントデータ});
ためし
※a00001のuser_profをまるっと違う値でsaveしてみる >db.test.save({"_id": "a00001", "user_info" : {"name": "hoge", "age": 10}, "user_prof" : {"nemui": 0, "darui": 0 } }) ※表示 -> まるっと更新されている >db.test.find({ "_id" : "a00001"}) { "_id" : "a00001", "user_info" : { "name" : "hoge", "age" : 10 }, "user_prof" : { "nemui" : 0, "darui" : 0 } } ※無いデータのa00006をsaveしてみる >db.test.insert({"_id": "a00006", "user_info" : {"name": "dare", "age": 60}, "user_prof" : {"work": 1, "smorker": 1 } }) ※表示 -> 追加されてる >db.test.find() { "_id" : "a00001", "user_info" : { "name" : "hoge", "age" : 10 }, "user_prof" : { "nemui" : 0, "darui" : 0 } } { "_id" : "a00002", "user_info" : { "name" : "fuga", "age" : 21 }, "user_prof" : { "work" : 1, "smorker" : 0 } } { "_id" : "a00003", "user_info" : { "name" : "piyo", "age" : 33 }, "user_prof" : { "work" : 1, "smorker" : 1 } } { "_id" : "a00004", "user_info" : { "name" : "waru", "age" : 40 }, "user_prof" : { "work" : 0, "smorker" : 1 } } { "_id" : "a00005", "user_info" : { "name" : "waru", "age" : 40 }, "user_prof" : { "work" : 0, "smorker" : 1 } } { "_id" : "a00006", "user_info" : { "name" : "dare", "age" : 60 }, "user_prof" : { "work" : 1, "smorker" : 1 } }
やってみた所感としては
行動ログなんかのデータをユーザごとに、
・無ければある固定ドキュメントでinsert
・あったらupdate&upsert
みたいな感じよりは固定のデータでsaveのほうが使いやすそう?
※速度的な感じは検証してないので今度にでもやってみます
6.NOUPDATE or INSERT的な(update, $setOnInsert, upsert)
基本構文
db.コレクション名.update({条件}, { $setOnInsert: {更新するドキュメントデータ} }, {upsert: true});
upsert(update + insert)は、
・存在すればupdate
・存在しなければinsert
ですが、$setOnInsetを指定することで存在しなければ初期値としてINSERT、UPDATEの場合は無視みたいです。
ためし
※やる前のa00001を表示 >db.test.find({ "_id" : "a00001"}) { "_id" : "a00001", "user_info" : { "name" : "hoge", "age" : 10 }, "user_prof" : { "nemui" : 0, "darui" : 0 } } ※a00001のuser_infoをsetOnInsert&upsert=trueでupdateしてみる >db.test.update({"_id": "a00001"}, {$setOnInsert:{"user_info": { "baka" : 0, "aho" : 0 }}}, {upsert: true}) ※a00001は更新されてない >db.test.find({ "_id" : "a00001"}) { "_id" : "a00001", "user_info" : { "name" : "hoge", "age" : 10 }, "user_prof" : { "nemui" : 0, "darui" : 0 } } ※a00001のuser_infoをsetOnInsert&upsert=falseでupdateしてみる >db.test.update({"_id": "a00001"}, {$setOnInsert:{"user_info": { "baka" : 0, "aho" : 0 }}}, {upsert: false}) ※falseでもa00001は更新されてない >db.test.find({ "_id" : "a00001"}) { "_id" : "a00001", "user_info" : { "name" : "hoge", "age" : 10 }, "user_prof" : { "nemui" : 0, "darui" : 0 } } ※a00001のまだ存在しないkeyドキュメントをsetOnInsert&upsert=falseでupdateしてみる >db.test.update({"_id": "a00001"}, {$setOnInsert:{"tekitou": { "baka" : 0, "aho" : 0 }}}, {upsert: false}) ※falseでもa00001は更新されてない >db.test.find({ "_id" : "a00001"}) { "_id" : "a00001", "user_info" : { "name" : "hoge", "age" : 10 }, "user_prof" : { "nemui" : 0, "darui" : 0 } } ※a00001のまだ存在しないkeyドキュメントをsetOnInsert&upsert=trueでupdateしてみる >db.test.update({"_id": "a00001"}, {$setOnInsert:{"tekitou": { "baka" : 0, "aho" : 0 }}}, {upsert: true}) ※falseでもa00001は更新されてない >db.test.find({ "_id" : "a00001"}) { "_id" : "a00001", "user_info" : { "name" : "hoge", "age" : 10 }, "user_prof" : { "nemui" : 0, "darui" : 0 } } ※存在しないa00007をsetOnInsert&upsert=trueでupdateしてみる >db.test.update({"_id": "a00007"}, {$setOnInsert:{"tekitou": { "baka" : 0, "aho" : 0 }}}, {upsert: true}) ※a00007が追加されてる >db.test.find() { "_id" : "a00001", "user_info" : { "name" : "hoge", "age" : 10 }, "user_prof" : { "nemui" : 0, "darui" : 0 } } { "_id" : "a00002", "user_info" : { "name" : "fuga", "age" : 21 }, "user_prof" : { "work" : 1, "smorker" : 0 } } { "_id" : "a00003", "user_info" : { "name" : "piyo", "age" : 33 }, "user_prof" : { "work" : 1, "smorker" : 1 } } { "_id" : "a00004", "user_info" : { "name" : "waru", "age" : 40 }, "user_prof" : { "work" : 0, "smorker" : 1 } } { "_id" : "a00005", "user_info" : { "name" : "waru", "age" : 40 }, "user_prof" : { "work" : 0, "smorker" : 1 } } { "_id" : "a00006", "user_info" : { "name" : "dare", "age" : 60 }, "user_prof" : { "work" : 1, "smorker" : 1 } } { "_id" : "a00007", "tekitou" : { "baka" : 0, "aho" : 0 } } ※存在しないa00008をsetOnInsert&upsert=falseでupdateしてみる >db.test.update({"_id": "a00008"}, {$setOnInsert:{"tekitou": { "baka" : 0, "aho" : 0 }}}, {upsert: false}) ※a00008は追加されない >db.test.find() { "_id" : "a00001", "user_info" : { "name" : "hoge", "age" : 10 }, "user_prof" : { "nemui" : 0, "darui" : 0 } } { "_id" : "a00002", "user_info" : { "name" : "fuga", "age" : 21 }, "user_prof" : { "work" : 1, "smorker" : 0 } } { "_id" : "a00003", "user_info" : { "name" : "piyo", "age" : 33 }, "user_prof" : { "work" : 1, "smorker" : 1 } } { "_id" : "a00004", "user_info" : { "name" : "waru", "age" : 40 }, "user_prof" : { "work" : 0, "smorker" : 1 } } { "_id" : "a00005", "user_info" : { "name" : "waru", "age" : 40 }, "user_prof" : { "work" : 0, "smorker" : 1 } } { "_id" : "a00006", "user_info" : { "name" : "dare", "age" : 60 }, "user_prof" : { "work" : 1, "smorker" : 1 } } { "_id" : "a00007", "tekitou" : { "baka" : 0, "aho" : 0 } }
なるほど。
やってみた所感としては、$setOnInsertとupsert=trueを組み合わせることで
・間違って上書きとかしたくない
&
でも処理コケたくない
みたいな場合に使うって感じでしょうか。
※INSERTだとduplicate key error indexとか出るので。
少しだけしかやれてませんが、まだまだ覚えなきゃ使いこなせないですね(>_<)