MongoDB를 이용 할 때 가장 짜증나는게 질의어 만들기다. 익숙함의 문제라고 하는 개발자도 있지만, SQL과 비교해서 보자면 근본적인 문제점을 가지고 있다. 요즘은 언어세대라는 용어를 별로 쓰지 않는 것 같은데, 이 분류를 따르자면 SQL은 4세대 언어다. 즉 인간의 언어와 매우 비슷한 문법을 가지고 있다는 이야기다. 아래 예제를 보자.
SELECT person, SUM(score), AVG(score), MIN(score), MAX(score), COUNT(*)
FROM demo
WHERE score > 0 AND person IN('bob','jake')
GROUP BY person;
SQL 언어를 처음 보는 사람이라고 하더라도 간단한 설명만으로 어떤일을 하는 질의어라는 걸 한번에 이해 할 수 있을 것이다. 몇 번만 연습하면 응용을 할 수 있을 테고, 메뉴얼을 읽지 않더라도 왠만한 질의어는 만들어 사용 할 수 있을 것이다. 몽고디비는 자바스크립트 문법을 사용하는데, SQL에 비하면 상상도 할 수 없을 만큼 어렵다. 위의 SQL을 몽고디비 쿼리로 변경했다.
이러한 질의어를 만들 수 있을까 ? 물론 몽고디비는 SQL과는 목적이 다르므로, 질의과정에서 연산을 수행하는 쿼리를 만드는 것은 불공정한 예제라고 할 수 있겠다. 요는 "SQL에 비하면 엄청나게 복잡하다"는 거다. http://www.querymongo.com/와 같은 사이트를 이용하거나 다른 툴들이 필요 할 수 있다. 애초에 뭔가 연산이 복잡해 질 것 같으면 SQL을 이용하는 데이터베이스를 사용하는게 좋다.
Contents
Mongodb Find 예제
SELECT person, SUM(score), AVG(score), MIN(score), MAX(score), COUNT(*) FROM demo WHERE score > 0 AND person IN('bob','jake') GROUP BY person;db.demo.group({ "key": { "person": true }, "initial": { "sumscore": 0, "sumforaverageaveragescore": 0, "countforaverageaveragescore": 0, "countstar": 0 }, "reduce": function(obj, prev) { prev.sumscore = prev.sumscore + obj.score - 0; prev.sumforaverageaveragescore += obj.score; prev.countforaverageaveragescore++; prev.minimumvaluescore = isNaN(prev.minimumvaluescore) ? obj.score : Math.min(prev.minimumvaluescore, obj.score); prev.maximumvaluescore = isNaN(prev.maximumvaluescore) ? obj.score : Math.max(prev.maximumvaluescore, obj.score); if (true != null) if (true instanceof Array) prev.countstar += true.length; else prev.countstar++; }, "finalize": function(prev) { prev.averagescore = prev.sumforaverageaveragescore / prev.countforaverageaveragescore; delete prev.sumforaverageaveragescore; delete prev.countforaverageaveragescore; }, "cond": { "score": { "$gt": 0 }, "person": { "$in": ["bob", "jake"] } } });테스트 데이터 준비
find 기본
> db.zips.find() { "_id" : "01001", "city" : "AGAWAM", "loc" : [ -72.622739, 42.070206 ], "pop" : 15338, "state" : "MA" } { "_id" : "01002", "city" : "CUSHMAN", "loc" : [ -72.51565, 42.377017 ], "pop" : 36963, "state" : "MA" } { "_id" : "01005", "city" : "BARRE", "loc" : [ -72.108354, 42.409698 ], "pop" : 4546, "state" : "MA" } { "_id" : "01007", "city" : "BELCHERTOWN", "loc" : [ -72.410953, 42.275103 ], "pop" : 10579, "state" : "MA" } { "_id" : "01008", "city" : "BLANDFORD", "loc" : [ -72.936114, 42.182949 ], "pop" : 1240, "state" : "MA" } { "_id" : "01010", "city" : "BRIMFIELD", "loc" : [ -72.188455, 42.116543 ], "pop" : 3706, "state" : "MA" } { "_id" : "01011", "city" : "CHESTER", "loc" : [ -72.988761, 42.279421 ], "pop" : 1688, "state" : "MA" } ..... Type "it" for more >특정 필드만 반환하기
> db.zips.find({},{city:1}) { "_id" : "01001", "city" : "AGAWAM" } { "_id" : "01002", "city" : "CUSHMAN" } { "_id" : "01005", "city" : "BARRE" } { "_id" : "01007", "city" : "BELCHERTOWN" } ....> db.zips.find({},{city:1, pop:1}) { "_id" : "01001", "city" : "AGAWAM", "pop" : 15338 } { "_id" : "01002", "city" : "CUSHMAN", "pop" : 36963 } { "_id" : "01005", "city" : "BARRE", "pop" : 4546 }Exact matching
문법 : {field: "찾기 원하는 값"}> db.zips.find({city:"NEW YORK"}) { "_id" : "10001", "city" : "NEW YORK", "loc" : [ -73.996705, 40.74838 ], "pop" : 18913, "state" : "NY" } { "_id" : "10002", "city" : "NEW YORK", "loc" : [ -73.987681, 40.715231 ], "pop" : 84143, "state" : "NY" } { "_id" : "10003", "city" : "NEW YORK", "loc" : [ -73.989223, 40.731253 ], "pop" : 51224, "state" : "NY" } ....비교 일치
문법 : {field: {$lt: value}}> db.zips.find({pop:{$gt:100, $lt:200}}) { "_id" : "01012", "city" : "CHESTERFIELD", "loc" : [ -72.833309, 42.38167 ], "pop" : 177, "state" : "MA" } { "_id" : "01032", "city" : "GOSHEN", "loc" : [ -72.844092, 42.466234 ], "pop" : 122, "state" : "MA" } { "_id" : "01258", "city" : "SOUTH EGREMONT", "loc" : [ -73.456575, 42.101153 ], "pop" : 135, "state" : "MA" } { "_id" : "01346", "city" : "HEATH", "loc" : [ -72.839101, 42.685347 ], "pop" : 174, "state" : "MA" } { "_id" : "02836", "city" : "RICHMOND", "loc" : [ -71.683992, 41.477694 ], "pop" : 183, "state" : "RI" } { "_id" : "02872", "city" : "PRUDENCE ISLAND", "loc" : [ -71.311827, 41.613606 ], "pop" : 150, "state" : "RI" } { "_id" : "03231", "city" : "EAST ANDOVER", "loc" : [ -71.759606, 43.47766 ], "pop" : 177, "state" : "NH" } { "_id" : "03268", "city" : "SALISBURY", "loc" : [ -71.704468, 43.406652 ], "pop" : 140, "state" : "NH" }배열에서의 Find
> db.zips.find({'loc.0':{$gt:-72.2, $lt:-72.1}},{city:1, loc:1}) { "_id" : "01005", "city" : "BARRE", "loc" : [ -72.108354, 42.409698 ] } { "_id" : "01010", "city" : "BRIMFIELD", "loc" : [ -72.188455, 42.116543 ] } { "_id" : "01031", "city" : "GILBERTVILLE", "loc" : [ -72.198585, 42.332194 ] } { "_id" : "01366", "city" : "PETERSHAM", "loc" : [ -72.189349, 42.489761 ] } { "_id" : "01518", "city" : "FISKDALE", "loc" : [ -72.117764, 42.122762 ] } { "_id" : "01521", "city" : "HOLLAND", "loc" : [ -72.154373, 42.040264 ] }정렬
> db.zips.find({city:"NEW YORK"}).sort({pop:1}) { "_id" : "10006", "city" : "NEW YORK", "loc" : [ -74.013474, 40.708451 ], "pop" : 119, "state" : "NY" } { "_id" : "10005", "city" : "NEW YORK", "loc" : [ -74.008344, 40.705649 ], "pop" : 202, "state" : "NY" } { "_id" : "10020", "city" : "NEW YORK", "loc" : [ -73.982347, 40.759729 ], "pop" : 393, "state" : "NY" } { "_id" : "10007", "city" : "NEW YORK", "loc" : [ -74.007022, 40.713905 ], "pop" : 3374, "state" : "NY" } ......> db.zips.find({city:"NEW YORK"}).sort({pop:-1}) { "_id" : "10021", "city" : "NEW YORK", "loc" : [ -73.958805, 40.768476 ], "pop" : 106564, "state" : "NY" } { "_id" : "10025", "city" : "NEW YORK", "loc" : [ -73.968312, 40.797466 ], "pop" : 100027, "state" : "NY" } { "_id" : "10002", "city" : "NEW YORK", "loc" : [ -73.987681, 40.715231 ], "pop" : 84143, "state" : "NY" } { "_id" : "10029", "city" : "NEW YORK", "loc" : [ -73.94475, 40.791817 ], "pop" : 74643, "state" : "NY" } { "_id" : "10024", "city" : "NEW YORK", "loc" : [ -73.976385, 40.786446 ], "pop" : 65141, "state" : "NY" } { "_id" : "10032", "city" : "NEW YORK", "loc" : [ -73.941978, 40.83819 ], "pop" : 61332, "state" : "NY" } ......limit 와 skip
> db.zips.find({city:"NEW YORK"},{city:1, pop:1}).sort({pop:-1}).limit(5) { "_id" : "10021", "city" : "NEW YORK", "pop" : 106564 } { "_id" : "10025", "city" : "NEW YORK", "pop" : 100027 } { "_id" : "10002", "city" : "NEW YORK", "pop" : 84143 } { "_id" : "10029", "city" : "NEW YORK", "pop" : 74643 } { "_id" : "10024", "city" : "NEW YORK", "pop" : 65141 }> db.zips.find({city:"NEW YORK"},{city:1, pop:1}).sort({pop:-1}).limit(5).skip(3) { "_id" : "10029", "city" : "NEW YORK", "pop" : 74643 } { "_id" : "10024", "city" : "NEW YORK", "pop" : 65141 } { "_id" : "10032", "city" : "NEW YORK", "pop" : 61332 } { "_id" : "10033", "city" : "NEW YORK", "pop" : 58648 } { "_id" : "10009", "city" : "NEW YORK", "pop" : 57426 }Recent Posts
Archive Posts
Tags