조건 쿼리
$lt, $lte, $gt, $gte
각각 <, <=, >, >=에 대응한다.
// 18세에서 30세 사이의 사용자
model.find({"age" : {"$gte" : 18 "$lte" : 30}});
$ne
not equal로 같지 않음을 표현
// john이 아닌 모든 사용자
model.find({"name" : {"$ne" : "john"}})
$in, $or
조건에 일치하는 도큐먼트를 찾는다.
$in은 다른 데이터형도 사용 가능하다. 반대로 배열 내 조건과 일치하지 않는 도큐먼트는 $nin
// $in
// 이름이 smaivnn이거나 potpae인 사용자를 찾는다.
model.find({"name" : {"$in" : ["smaivnn", "potpae"]}})
$or은 조건들의 배열을 취한다. 또한 다른 조건절을 포함할 수도 있다.
// smaivnn와 potpae중 이름이 하나라도 일치하거나 gender가 true라면 반환.
model.find({"$or" : [{"name" : {"$in" : ["smaivnn", "potpae"]}},
{"gender" : true}]})
배열 쿼리
$all
일치하는 요소 찾기
// {"name" : ["smaivnn", "john", "doe"]}
// smaivnn과 일치하는 도큐먼트 찾기
model.find({"name" : "smaivnn"});
배열에 2개 이상 일치하는 요소 찾기 $all 이용
// "name"에 smaivnn, john항목이 있는 다큐먼트 반환
model.find({"name" : {$all : ["smaivnn", "john"]}})
배열 내 특정 위치 요소 쿼리
// 0부터 시작하는 배열의 인덱스에서 1번째 요소게 "doe"가 있는지 확인
model.find({"name.1" : "doe"})
$slice
배열의 부분집합 반환
// 조건에 맞는 도큐먼트의 comments배열에서 상위(먼저 달린) 10개 반환받기.
model.findOne(조건, {"comments" : {"$slice" : 10}})
// 조건에 맞는 도큐먼트의 comments배열에서 하위(나중에 달린) 10개 반환받기.
model.findOne(조건, {"comments" : {"$slice" : -10}})
// offset과 이용하여 범위 안에 결과 반환받기
// 처음 23개 건너 뛰고 24번째 요소부터 10개 뒤인 33번째 까지의 요소 반환.
// 요소가 충분하지 않다면 현재 있는 요소까지 반환.
model.findOne(조건, {"comments" : {"$slice" : [23, 10] }})
$
일치하는 요소 반환 받기
// smaivnn이 쓴 댓글을 반환받는다.
// 첫 번째로 일치하는 댓글만 반환한다.
model.find({"comments.name" : "smaivnn"}, {"comments.$" : 1})
$elemMatch
내장 도큐먼트를 찾을때는 보통 내장 도큐먼트가 쿼리 도큐먼트와 전체가 정확히 일치해야한다.
// "name" : {"first" : "john", "last" : "doe"}와 정확히 같아야함.
model.find({"name" : {"first" : "john", "last" : "doe"}})
이를 위해 점 표기법을 사용한다.
// 혹시 "name"항목에 추가 사항이 있더라도 여전히 성과 이름으로 찾는다.
model.find({"name.first" : "john", "name.last" : "doe"})
하지만 이 경우 name.first가 john인, 그리고 name.last가 doe인 각기 다른 도큐먼트가 있다면 그것 또한 반환한다.
따라서 이럴 때 키를 지정하지 않고 정확히 묶기 위해 $elemMatch를 사용한다.
// 2개 이상 키의 조건 일치 여부 확인.
model.find({"comments" : {"$elemMatch" : {"author" : "john", "score" : {"$gte" : 5}}})
커서
find()의 결과를 반환하는 것이다.
.limit()
// 조건에 맞는 결과 3개만 반환한다.
model.find().limit(3)
.sort
// 오름/내림차순으로 정렬한다.
// 1은 오름차순, -1은 내림차순
model.find().sort({username: 1, age : -1})
.skip
// 찾은 것 중 처음 3개를 건너뛴다.
model.find().skip(3)
하지만 skip()은 생략된 부분들을 모두 폐기하므로 결과가 많다면 성능의 저하를 가져온다.
skip을 사용하지 않고 페이지를 나누는 법
limit 을 이용해 첫 페이지를 반환하고, 다음 페이지 부터는 첫 페이지부터 오프셋을 주어 반환한다.
예를 들어, 첫 페이지는 다음과 같이 구성한다.
let page = model.find().sort({"date" : -1}).limit(100)
이후, 다음 페이지 부터는 마지막 도큐먼트의 "date" 값을 기준으로 가져온다.
let latest = null;
// 첫 페이지 보여주기
while(page1.hasNext()_ {
latest = page1.next();
display(latest);
}
// 다음 페이지 가져오기
let page2 = model.find({"date" : {"$lt" : latest.date}});
page2.sort({"date" : -1}).limit(100);
본 게시물은 한빛미디어의 <MongoDB The Definitive Guide 몽고DB 완벽 가이드 3>을 요약 정리했습니다.
'Database' 카테고리의 다른 글
[mongoDB] 집계 프레임워크 (0) | 2023.03.25 |
---|---|
[mongoDB] 인덱스 (0) | 2023.03.24 |
[mongoDB] 갱신 연산자 (0) | 2023.03.15 |