Post List

2015년 8월 2일 일요일

MongoDB Study #05 연산자 (Operator) 및 검색 (find)

1. 비교연산자

   비교연산자는 Boolean Type을 return 합니다. ($cmp 제외)
   즉, 그 결과는 True 또는 False 입니다.

$cmp : 두 값을 비교하여 앞의 값이 크면 양수, 작으면 음수, 같으면 0을 return 합니다.
$eq : 두 값이 같으면 True, 다르면 False
$gt : 앞의 값이 크면 True, 작거나 같으면 False
$gte : 앞의 값이 크거나 같으면 True, 작으면 False
$lt : 앞의 값이 작으면 True, 크거나 같으면 False
$lte : 앞의 값이 작거나 같으면 True, 크면 False
$ne : 두 값이 다르면 True, 같으면 False

다음은 여러 개의 Boolean 값을 비교하여 Boolean Type을 return 하는 함수들 입니다.

$and : 모두 True이면 True
$or : 하나라도 True이면 True
$not : 해당 결과값의 반대

이제 실습예제를 살펴보겠습니다.
아래 예제는 http://www.pitmongo.co.kr -> 고객지원 -> 기술자료 폴더 -> [실습파일] MongoDB Master가 해설하는 NoSQL&MongoDB 교재 관련 -> employees.json 파일의 내용으로 collection을 생성 한 후에 진행하였습니다.
그리고 RDBMS의 SQL은 Oracle에서 Orange Tool을 이용하여 진행하였습니다.

SELECT * FROM SCOTT.EMP;



db.employees.find({},{_id:0})
{ "empno" : 7369, "ename" : "SMITH", "job" : "CLERK", "hiredate" : "17-12-1980", "sal" : 800, "deptno" : 20 }
{ "empno" : 7499, "ename" : "ALLEN", "job" : "SALESMAN", "hiredate" : "20-02-1981", "sal" : 1600, "comm" : 300, "deptno" : 30 }
{ "empno" : 7521, "ename" : "WARD", "job" : "SALESMAN", "hiredate" : "22-02-1981", "sal" : 1250, "comm" : 500, "deptno": 30 }
{ "empno" : 7566, "ename" : "JONES", "job" : "MANAGER", "hiredate" : "02-04-1981", "sal" : 2975, "deptno" : 20 }
{ "empno" : 7654, "ename" : "MARTIN", "job" : "SALESMAN", "hiredate" : "28-09-1981", "sal" : 1250, "comm" : 1400, "deptno" : 30 }
{ "empno" : 7698, "ename" : "BLAKE", "job" : "MANAGER", "hiredate" : "01-05-1981", "sal" : 2850, "deptno" : 30 }
{ "empno" : 7782, "ename" : "CLARK", "job" : "MANAGER", "hiredate" : "09-06-1981", "sal" : 2450, "deptno" : 10 }
{ "empno" : 7788, "ename" : "SCOTT", "job" : "ANALYST", "hiredate" : "13-06-1987", "sal" : 3000, "deptno" : 20 }
{ "empno" : 7839, "ename" : "PRESIDENT", "job" : "CEO", "hiredate" : "17-11-1981", "sal" : 5000, "deptno" : 10 }
{ "empno" : 7844, "ename" : "TURNER", "job" : "SALESMAN", "hiredate" : "08-09-1981", "sal" : 1500, "deptno" : 30 }
{ "empno" : 7876, "ename" : "ADAMS", "job" : "CLERK", "hiredate" : "13-06-1987", "sal" : 1100, "deptno" : 20 }
{ "empno" : 7900, "ename" : "JAMES", "job" : "CLERK", "hiredate" : "03-12-1981", "sal" : 950, "deptno" : 30 }
{ "empno" : 7902, "ename" : "FORD", "job" : "ANALYST", "hiredate" : "03-12-1981", "sal" : 3000, "deptno" : 20 }
{ "empno" : 7934, "ename" : "CLERK", "job" : "CLERK", "hiredate" : "23-01-1982", "sal" : 1300, "deptno" : 10 }

SELECT * FROM SCOTT.EMP WHERE EMPNO = 7369



db.employees.find({empno:7369}).forEach(printjson)
{
        "_id" : ObjectId("55bdc94b2f09f58dc18448e8"),
        "empno" : 7369,
        "ename" : "SMITH",
        "job" : "CLERK",
        "hiredate" : "17-12-1980",
        "sal" : 800,
        "deptno" : 20
}

SELECT ROWID, ENAME FROM SCOTT.EMP WHERE EMPNO = 7900



db.employees.find({empno:7900}, {ename:""}).forEach(printjson)
{ "_id" : ObjectId("55bdc94b2f09f58dc18448f3"), "ename" : "JAMES" }

CREATE INDEX SCOTT.EMP_ENAME ON SCOTT.EMP (ENAME);
SELECT empno, ename FROM SCOTT.EMP WHERE ENAME >= 'ALLEN' AND ENAME < 'SCOTT'



> db.employees.ensureIndex({ename:1})
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
}
db.employees.find({},{_id:0, empno:1, ename:1}).min({ename:"ALLEN"}).max({ename:"SCOTT"})
{ "empno" : 7499, "ename" : "ALLEN" }
{ "empno" : 7698, "ename" : "BLAKE" }
{ "empno" : 7782, "ename" : "CLARK" }
{ "empno" : 7934, "ename" : "CLERK" }
{ "empno" : 7902, "ename" : "FORD" }
{ "empno" : 7900, "ename" : "JAMES" }
{ "empno" : 7566, "ename" : "JONES" }
{ "empno" : 7654, "ename" : "MARTIN" }
{ "empno" : 7839, "ename" : "PRESIDENT" }

CREATE INDEX SCOTT.EMP_DEPTNO ON SCOTT.EMP (DEPTNO);
SELECT EMPNO, ENAME, HIREDATE FROM SCOTT.EMP WHERE DEPTNO BETWEEN 20 AND 30;

(이하 결과 그림은 생략하겠습니다.)


> db.employees.ensureIndex({deptno:1})
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 2,
        "numIndexesAfter" : 3,
        "ok" : 1
}
> db.employees.find({$min:{deptno:20}, $max:{deptno:30}, $query:{}}, {_id:0, empno:1, ename:1, hiredate:1})
{ "empno" : 7369, "ename" : "SMITH", "hiredate" : "17-12-1980" }
{ "empno" : 7566, "ename" : "JONES", "hiredate" : "02-04-1981" }
{ "empno" : 7788, "ename" : "SCOTT", "hiredate" : "13-06-1987" }
{ "empno" : 7876, "ename" : "ADAMS", "hiredate" : "13-06-1987" }
{ "empno" : 7902, "ename" : "FORD", "hiredate" : "03-12-1981" }

SELECT EMPNO, ENAME FROM SCOTT.EMP WHERE EMPNO > 7500 AND EMPNO <= 7600;

> db.employees.find({empno:{$gt:7500, $lte:7600}}, {_id:0,empno:1,ename:1})
{ "empno" : 7521, "ename" : "WARD" }
{ "empno" : 7566, "ename" : "JONES" }

SELECT EMPNO FROM SCOTT.EMP WHERE EMPNO = 7782 OR EMPNO = 7844;

> db.employees.find({$or:[{empno:7782},{empno:7844}]}, {_id:0, empno:1})
{ "empno" : 7782 }
{ "empno" : 7844 }

SELECT COUNT(*) FROM SCOTT.EMP;
SELECT COUNT(*) FROM SCOTT.EMP WHERE EMPNO > 7900;


> db.employees.count()
14
> db.employees.find({empno: {'$gt':7900}}).count()
2

SELECT DISTICT DEPTNO FROM SCOTT.EMP;


> db.employees.distinct("deptno")
[ 10, 20, 30 ]

SELECT DEPTNO, SUM(SAL) CSUM FROM SCOTT.EMP
 WHERE HIREDATE >= '01-01-1980' AND HIREDATE <= '31-12-1981' GROUP BY DEPTNO;

db.employees.group({key: {deptno:true}, cond: {"hiredate": {$gte: "01-01-1980", $lt: "31-12-1981"}}, reduce: function(obj, prev) {prev.csum += obj.sal; }, initial: { csum:0}})
[
        {
                "deptno" : 20,
                "csum" : 10875
        },
        {
                "deptno" : 30,
                "csum" : 9400
        },
        {
                "deptno" : 10,
                "csum" : 8750
        }
]

SELECT ENAME, JOB FROM SCOTT.EMP WHERE DEPTNO = 10 ORDER BY ENAME DESC;


> db.employees.find({deptno:10},{_id:0, ename:1, job:1}).sort({ename:-1})
{ "ename" : "PRESIDENT", "job" : "CEO" }
{ "ename" : "CLERK", "job" : "CLERK" }
{ "ename" : "CLARK", "job" : "MANAGER" }

SELECT EMPNO, ENAME FROM SCOTT.EMP WHERE SAL <= 1000;


db.employees.find({sal:{$lte:1000}}, {_id:0, empno:"", ename:""})
{ "empno" : 7369, "ename" : "SMITH" }
{ "empno" : 7900, "ename" : "JAMES" }

SELECT EMPNO, ENAME, SAL FROM SCOTT.EMP WHERE SAL >= 1500 AND SAL <= 5000;


> db.employees.find({sal:{$gte:1500, $lte:5000}}, {_id:0, empno:1, ename:1, sal:1})
{ "empno" : 7499, "ename" : "ALLEN", "sal" : 1600 }
{ "empno" : 7566, "ename" : "JONES", "sal" : 2975 }
{ "empno" : 7698, "ename" : "BLAKE", "sal" : 2850 }
{ "empno" : 7782, "ename" : "CLARK", "sal" : 2450 }
{ "empno" : 7788, "ename" : "SCOTT", "sal" : 3000 }
{ "empno" : 7839, "ename" : "PRESIDENT", "sal" : 5000 }
{ "empno" : 7844, "ename" : "TURNER", "sal" : 1500 }
{ "empno" : 7902, "ename" : "FORD", "sal" : 3000 }

SELECT EMPNO, DEPTNO FROM SCOTT.EMP WHERE DEPTNO IN ( 10, 30);


> db.employees.find({deptno:{$in:[10,30]}}, {_id:0, empno:1, deptno:1})
{ "empno" : 7782, "deptno" : 10 }
{ "empno" : 7839, "deptno" : 10 }
{ "empno" : 7934, "deptno" : 10 }
{ "empno" : 7499, "deptno" : 30 }
{ "empno" : 7521, "deptno" : 30 }
{ "empno" : 7654, "deptno" : 30 }
{ "empno" : 7698, "deptno" : 30 }
{ "empno" : 7844, "deptno" : 30 }
{ "empno" : 7900, "deptno" : 30 }

SELECT EMPNO, ENAME FROM SCOTT.EMP WHERE DEPTNO = 10 OR DEPTNO = 30;


> db.employees.find({$or:[{deptno:10}, {deptno:30}]}, {_id:0, empno:1, ename:1})
{ "empno" : 7782, "ename" : "CLARK" }
{ "empno" : 7839, "ename" : "PRESIDENT" }
{ "empno" : 7934, "ename" : "CLERK" }
{ "empno" : 7499, "ename" : "ALLEN" }
{ "empno" : 7521, "ename" : "WARD" }
{ "empno" : 7654, "ename" : "MARTIN" }
{ "empno" : 7698, "ename" : "BLAKE" }
{ "empno" : 7844, "ename" : "TURNER" }
{ "empno" : 7900, "ename" : "JAMES" }

SELECT EMPNO, DEPTNO FROM SCOTT.EMP WHERE DEPTNO = 10 AND SAL > 1000;


> db.employees.find({$and:[{deptno:10}, {sal:{$gt:1000}}]}, {_id:0, empno:1, deptno:1})
{ "empno" : 7782, "deptno" : 10 }
{ "empno" : 7839, "deptno" : 10 }
{ "empno" : 7934, "deptno" : 10 }

SELECT EMPNO, COMM FROM SCOTT.EMP WHERE COMM IS NOT NULL;


> db.employees.find({comm:{$exists:true}}, {_id:0, empno:1, comm:1})
{ "empno" : 7499, "comm" : 300 }
{ "empno" : 7521, "comm" : 500 }
{ "empno" : 7654, "comm" : 1400 }

SELECT EMPNO, COMM FROM SCOTT.EMP WHERE COMM IS NULL;

> db.employees.find({comm:{$exists:false}},{_id:0, empno:1, comm:1})
{ "empno" : 7369 }
{ "empno" : 7566 }
{ "empno" : 7698 }
{ "empno" : 7782 }
{ "empno" : 7788 }
{ "empno" : 7839 }
{ "empno" : 7844 }
{ "empno" : 7876 }
{ "empno" : 7900 }
{ "empno" : 7902 }
{ "empno" : 7934 }

2. 변경 연산자

- 산술 연산자

$add : 두 값을 합칩니다.
$devide : 앞의 값에서 뒤에서 값을 나눕니다.
$mod : 앞의 값에서 뒤의 값을 나눈 나머지 값을 return 합니다.
$multiply : 두 값을 곱합니다.
$subtract : 앞의 값에서 뒤의 값을 뺍니다.

- 문자 연산자

$strcasecmp : 앞의 문자열이 뒤의 문자열보다 크면 양수, 작으면 음수, 같으면 0을 return 합니다.
$substr : 앞의 문자열에서 첫번째 숫자 위치에서 두번째 숫자 길이만큼의 sub-string을 return 합니다.
$toUpper : 대문자로 return 합니다.
$toLower : 소문자로 return 합니다.

위 함수와는 다르지만 몇가지 더 검색하는 방법에 대해서 소개해 드리겠습니다.
아래에 소개할 방법은 RDBMS에서는 간단한 SQL문 만으로는 만들수 없는 종류들입니다.
물론 함수 등을 이용하여 표현이 다 가능한 방법이긴 합니다.

> db.employees.find({comm:{$type:1}},{empno:"", comm:""}) // comm 의 타입이 double 인것을 검색
{ "_id" : ObjectId("55bdc94b2f09f58dc18448e9"), "empno" : 7499, "comm" : 300 }
{ "_id" : ObjectId("55bdc94b2f09f58dc18448ea"), "empno" : 7521, "comm" : 500 }
{ "_id" : ObjectId("55bdc94b2f09f58dc18448ec"), "empno" : 7654, "comm" : 1400 }
> db.employees.find({comm:{$type:2}},{empno:"", comm:""}) // comm 의 타입이 string 인것을 검색
> db.employees.find({ename:{$regex:'S.*H', $options: 'i'}},{empno:1, ename:1}) // ename이 S로 시작해서 H로 끝나는 것을 검색, 'i' : 대소문자 구분 없음
{ "_id" : ObjectId("55bdc94b2f09f58dc18448e8"), "empno" : 7369, "ename" : "SMITH" }
> db.employees.find({ename:{$regex:'s.*h', $options: 'i'}},{empno:1, ename:1})
{ "_id" : ObjectId("55bdc94b2f09f58dc18448e8"), "empno" : 7369, "ename" : "SMITH" }
> db.employees.find({ename:{$regex:'s.*h', $options: 'm'}},{empno:1, ename:1})  // 'm' : 대소문자 구분함
> db.employees.find({ename:{$regex:'S.*H', $options: 'm'}},{empno:1, ename:1})
{ "_id" : ObjectId("55bdc94b2f09f58dc18448e8"), "empno" : 7369, "ename" : "SMITH" }


댓글 없음:

댓글 쓰기