SMAIVNN
article thumbnail
Published 2023. 3. 17. 23:06
[mongoDB] 쿼리 Database

조건 쿼리

$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
profile

SMAIVNN

@SMAIVNN

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!