mongoクエリーの基本ですが、
読めばわかるけど、使ってみて覚えるのが良いですよね!
かなり基本項目ですが
distinctとwhere句に使う$or、$and、$lte、$gteについての忘れないようにメモです
サンプルのながれはこんな感じ
1.サンプル入れる
2.distinct
3.$or
4.$and
5.$lte
6.$gte
7.distinctと複合条件サンプル
ってことで、サンプルデータを入れるところからやっておきます。
1.サンプル入れる
これから試すためのサンプルですが、てきとーに学校の成績データをmongoで管理してたらってゆー体でやります
サンプルデータを入れるスクリプト
/* ユーザ */ var users = [ {id: "a0001", "name": "hoge"}, {id: "a0002", "name": "piyo"}, {id: "a0003", "name": "fuga"} ] /* 学期 */ var terms = { "1": "first_term", "2": "second_term", "3": "third_term"}; /* 教科 */ var subjects = ["japanese", "math", "english"]; /* ランダムに点数を返却(1〜100) */ var markRamdom = function(){ return Math.floor(Math.random() * 100 + 1); } /* 成績データをinsert */ for(var idx in users){ for(var term in terms){ var tmpMarks = {}; for(var i in subjects){ tmpMarks[subjects[i]] = markRamdom(); } db.school_record.insert({ "info" : {"user_id": users[idx].id, "name": users[idx].name, "term": term}, "mark" : tmpMarks }) } }
結果
> db.school_record.find() { "_id" : ObjectId("532056e52ee9dde960cd50eb"), "info" : { "user_id" : "a0001", "name" : "hoge", "term" : "1" }, "mark" : { "japanese" : 70, "math" : 49, "english" : 13 } } { "_id" : ObjectId("532056e52ee9dde960cd50ec"), "info" : { "user_id" : "a0001", "name" : "hoge", "term" : "2" }, "mark" : { "japanese" : 11, "math" : 9, "english" : 97 } } { "_id" : ObjectId("532056e52ee9dde960cd50ed"), "info" : { "user_id" : "a0001", "name" : "hoge", "term" : "3" }, "mark" : { "japanese" : 19, "math" : 48, "english" : 38 } } { "_id" : ObjectId("532056e52ee9dde960cd50ee"), "info" : { "user_id" : "a0002", "name" : "piyo", "term" : "1" }, "mark" : { "japanese" : 16, "math" : 31, "english" : 38 } } { "_id" : ObjectId("532056e52ee9dde960cd50ef"), "info" : { "user_id" : "a0002", "name" : "piyo", "term" : "2" }, "mark" : { "japanese" : 63, "math" : 19, "english" : 32 } } { "_id" : ObjectId("532056e52ee9dde960cd50f0"), "info" : { "user_id" : "a0002", "name" : "piyo", "term" : "3" }, "mark" : { "japanese" : 34, "math" : 4, "english" : 76 } } { "_id" : ObjectId("532056e52ee9dde960cd50f1"), "info" : { "user_id" : "a0003", "name" : "fuga", "term" : "1" }, "mark" : { "japanese" : 58, "math" : 51, "english" : 1 } } { "_id" : ObjectId("532056e52ee9dde960cd50f2"), "info" : { "user_id" : "a0003", "name" : "fuga", "term" : "2" }, "mark" : { "japanese" : 78, "math" : 94, "english" : 86 } } { "_id" : ObjectId("532056e52ee9dde960cd50f3"), "info" : { "user_id" : "a0003", "name" : "fuga", "term" : "3" }, "mark" : { "japanese" : 47, "math" : 61, "english" : 15 } }
構造がこうのほうがいいんじゃね?とかってのは目をつむってくださいw
2.distinct
これは(uu)ユニークユーザとか求めるときはいいですよね
使い方
db.collection.distinct("distinctするKey", {"絞りこむ条件"})
とりあえずユニークなユーザを出してみる
>db.school_record.distinct("info.user_id") [ "a0001", "a0002", "a0003" ]
3.$or
使い方
条件1 or 条件2のパターンです
db.collection.find({$or: [{条件1}, {条件2}]})
ユーザが"hoge"または"piyo"さんを出してみる
> db.school_record.find({$or:[{"info.name": "hoge"}, {"info.name": "piyo"}]}) { "_id" : ObjectId("532056e52ee9dde960cd50eb"), "info" : { "user_id" : "a0001", "name" : "hoge", "term" : "1" }, "mark" : { "japanese" : 70, "math" : 49, "english" : 13 } } { "_id" : ObjectId("532056e52ee9dde960cd50ec"), "info" : { "user_id" : "a0001", "name" : "hoge", "term" : "2" }, "mark" : { "japanese" : 11, "math" : 9, "english" : 97 } } { "_id" : ObjectId("532056e52ee9dde960cd50ed"), "info" : { "user_id" : "a0001", "name" : "hoge", "term" : "3" }, "mark" : { "japanese" : 19, "math" : 48, "english" : 38 } } { "_id" : ObjectId("532056e52ee9dde960cd50ee"), "info" : { "user_id" : "a0002", "name" : "piyo", "term" : "1" }, "mark" : { "japanese" : 16, "math" : 31, "english" : 38 } } { "_id" : ObjectId("532056e52ee9dde960cd50ef"), "info" : { "user_id" : "a0002", "name" : "piyo", "term" : "2" }, "mark" : { "japanese" : 63, "math" : 19, "english" : 32 } } { "_id" : ObjectId("532056e52ee9dde960cd50f0"), "info" : { "user_id" : "a0002", "name" : "piyo", "term" : "3" }, "mark" : { "japanese" : 34, "math" : 4, "english" : 76 } }
慣れれば簡単ですが、最初はちょっと戸惑いましたw
直感で考えると"name"が"hoge"or"piyo"だから指定するkeyの書き出しは
find({"info.name": {$or:---省略---
みたいになるのかなって想像してましたw
4.$and
使い方
条件1 and 条件2のパターンです
db.collection.find({$and: [{条件1}, {条件2}]})
ユーザが"hoge"かつ、学期が"1"のドキュメントを出してみる
> db.school_record.find({$and:[{"info.name": "hoge"}, {"info.term": "1"}]}) { "_id" : ObjectId("532056e52ee9dde960cd50eb"), "info" : { "user_id" : "a0001", "name" : "hoge", "term" : "1" }, "mark" : { "japanese" : 70, "math" : 49, "english" : 13 } }
5.$lte
lteは記号だと「<=」です(左がkeyだとして)
eはequalなので、つけなければとうぜん「<」になります。
japaneseが20点以下の人出してみる
> db.school_record.find({"mark.japanese": {$lte: 20}}) { "_id" : ObjectId("532056e52ee9dde960cd50ec"), "info" : { "user_id" : "a0001", "name" : "hoge", "term" : "2" }, "mark" : { "japanese" : 11, "math" : 9, "english" : 97 } } { "_id" : ObjectId("532056e52ee9dde960cd50ed"), "info" : { "user_id" : "a0001", "name" : "hoge", "term" : "3" }, "mark" : { "japanese" : 19, "math" : 48, "english" : 38 } } { "_id" : ObjectId("532056e52ee9dde960cd50ee"), "info" : { "user_id" : "a0002", "name" : "piyo", "term" : "1" }, "mark" : { "japanese" : 16, "math" : 31, "english" : 38 } }
6.$gte
gteは記号だと「>=」です(左がkeyだとして)
あとはlteと同じですね
使い方
"あるkey"が"ある値"以上のパターンです
db.collection.find({"あるKey": {$gte: ある値}})
englishが90点以下の人出してみる
> db.school_record.find({"mark.english": {$gte: 90}}) { "_id" : ObjectId("532056e52ee9dde960cd50ec"), "info" : { "user_id" : "a0001", "name" : "hoge", "term" : "2" }, "mark" : { "japanese" : 11, "math" : 9, "english" : 97 } }
7.distinctと複合条件サンプル
ってことであとは混ぜてみるだけです
2学期に数学が10点以下の人
> db.school_record.find({$and:[ {"info.term": "2"}, {"mark.math": {$lte: 10}} ]}) { "_id" : ObjectId("532056e52ee9dde960cd50ec"), "info" : { "user_id" : "a0001", "name" : "hoge", "term" : "2" }, "mark" : { "japanese" : 11, "math" : 9, "english" : 97 } }
全学期、全教科を通して20点以下を取ったことあるドキュメント
"ドキュメント"って言葉がポイントですね
取ったことある人、の場合はこの次にdistinctでやります
> db.school_record.find({$or:[ {"mark.japanese": {$lte: 20}}, {"mark.math": {$lte: 20}}, {"mark.english": {$lte: 20}} ]}) { "_id" : ObjectId("532056e52ee9dde960cd50eb"), "info" : { "user_id" : "a0001", "name" : "hoge", "term" : "1" }, "mark" : { "japanese" : 70, "math" : 49, "english" : 13 } } { "_id" : ObjectId("532056e52ee9dde960cd50ec"), "info" : { "user_id" : "a0001", "name" : "hoge", "term" : "2" }, "mark" : { "japanese" : 11, "math" : 9, "english" : 97 } } { "_id" : ObjectId("532056e52ee9dde960cd50ed"), "info" : { "user_id" : "a0001", "name" : "hoge", "term" : "3" }, "mark" : { "japanese" : 19, "math" : 48, "english" : 38 } } { "_id" : ObjectId("532056e52ee9dde960cd50ee"), "info" : { "user_id" : "a0002", "name" : "piyo", "term" : "1" }, "mark" : { "japanese" : 16, "math" : 31, "english" : 38 } } { "_id" : ObjectId("532056e52ee9dde960cd50ef"), "info" : { "user_id" : "a0002", "name" : "piyo", "term" : "2" }, "mark" : { "japanese" : 63, "math" : 19, "english" : 32 } } { "_id" : ObjectId("532056e52ee9dde960cd50f0"), "info" : { "user_id" : "a0002", "name" : "piyo", "term" : "3" }, "mark" : { "japanese" : 34, "math" : 4, "english" : 76 } } { "_id" : ObjectId("532056e52ee9dde960cd50f1"), "info" : { "user_id" : "a0003", "name" : "fuga", "term" : "1" }, "mark" : { "japanese" : 58, "math" : 51, "english" : 1 } } { "_id" : ObjectId("532056e52ee9dde960cd50f3"), "info" : { "user_id" : "a0003", "name" : "fuga", "term" : "3" }, "mark" : { "japanese" : 47, "math" : 61, "english" : 15 } }
全学期、全教科を通して20点以下を取ったことある人
人だけ欲しいのでdistinctと↑の条件を使います
> db.school_record.distinct("info.name", {$or:[ {"mark.japanese": {$lte: 20}}, {"mark.math": {$lte: 20}}, {"mark.english": {$lte: 20}} ]}) [ "hoge", "piyo", "fuga" ]
結果全員でしたw
ってことで、基本中の基本ですが、あえて書いておいてみました(^-^v)