본문 바로가기
DataBase/NoSQL

[NoSQL] MongoDB 쿼리 언어 총정리2

by 스파이디웹 2021. 1. 20.
728x90

#자바스크립트 쿼리 연산자

-쿼리에 자바스크립트 표현식을 넘겨주기 위해서는 특수한 $where 연산자를 사용할 수 있다.

ex)

db.컬렉션이름.find({

        '$where': "function() {return this.helpful_votes > 3;}"

    })

//this는 현재의 도큐먼트를 가리킨다.

 

db.컬렉션이름.find({'$where': "this.helpful_votes > 3"})처럼 표현할 수 있다.

 

-자바스크림트 쿼리는 성능 저하 문제인젝션 공격에 노출되는 위험성을 가지고 있다.

 


#정규 표현식(regular expression)

-$regex연산자: 요소를 제공된 정규 표현식과 맞춰 본다.

 

-prefix 타입의 쿼리를 제외하고는 정규 표현식 쿼리는 인덱스를 사용할 수 없고, 대부분의 선택자보다 실행시간이 오래 걸린다.

 

-따라서 정규 표현식은 조금씩 사용할 것을 권한다.

 

-best나 worst라는 단어가 들어가고 대소문자를 구분하지 않는 쿼리

ex)

db.컬렉션이름.find({

    'user_id': ObjectId("~~~"),

    'text': /best|worst/i

   })

 

-정규 표현식을 지원하지 않는 환경에서는 $regex와 $options라는 특수한 연산자를 사용할 수 있다.

ex)

db.컬렉션이름.find({

    'user_id': ObjectId("~~~"),

    'text': {

              '$regex': "best|worst"

              '$options': "i"}

   })

 

-MongoDB는 대소문자를 구별하는 시스템이므로 옵션에 i 수정자를 사용하지 않으면 검색되는 필드의 대소문자와 정확히 일치해야 한다.


#그 밖의 쿼리 연산자

연산자 설명
$mod[(몫),(결과)] 몫으로 나눈 결과가 요소와 일치할 경우 일치
$type 요소의 타입이 명시된 BSON 타입과 일치할 경우 일치
$text 텍스트 인덱스로 인덱싱된 필드의 내용에 대해 텍스트 검색을 수행할 수 있도록 해준다.

-$mod 연산자는 두 개의 값으로 이루어진 배열을 갖는다.

첫 번째 값은 나누는 값, 두 번째 값은 나눈 후의 나머지 값.

ex)

주문 액수를 3으로 나누면 나머지가 0이 되는 모든 주문을 검색

db.컬렉션이름.find({subtotal: {$mod: [3,0]}})

 

-$mod 연산자를 사용하게 되면 인덱스를 사용하지 못한다.

 

$type 연산자는 값이 어떤 BSON 타입인지 확인해 준다.

 

BSON 타입

type number alias notes example
Double 1 “double”   123.456
String 2 “string”   "Now is the time"
Object 3 “object”   {name:"tim",age:"myob"}
Array 4 “array”   [123,2345,"string"]
Binary data 5 “binData”   BinData(2,"DgAAAEltIHNvbWUgYmluYXJ5")
Undefined 6 “undefined” Deprecated.  
ObjectId 7 “objectId”   ObjectId("4e1bdda65025ea6601560b50")
Boolean 8 “bool”   True
Date 9 “date”   ISODate("2021-01-20T14:32:00Z")
Null 10 “null”   null
Regular Expression 11 “regex”   /test/i
DBPointer 12 “dbPointer” Deprecated.  
JavaScript 13 “javascript”   function(){return false;}
Symbol 14 “symbol” Deprecated.  
JavaScript code with scope 15 “javascriptWithScope” Deprecated in MongoDB 4.4.  
32-bit integer 16 “int”   10
Timestamp 17 “timestamp”   {"t":1371429067,
"i" : 0
}
64-bit integer 18 “long”   NumberLong(10)
Decimal128 19 “decimal” New in version 3.4. {"$maxKey": 1}
Min key -1 “minKey”   {"$minKey" : 1}
Max key 127 “maxKey”   {"maxkey" : { "$maxKey" : 1}}

-maxkey와 minkey는 '가상'의 값을 입력하기 위해 사용되며, 최댓값 또는 최솟값 같은 뜻으로 쓰인다.

(정렬 인덱스를 사용할 때 도큐먼트가 첫 번째 또는 마지막 항목으로 정렬되도록 사용될 수 있음을 뜻한다.)


#쿼리 옵션

1)모든 쿼리에는 쿼리 셀렉터가 필요하다.

2)빈 셀렉터일지라도 쿼리 셀렉터는 본질적으로 쿼리를 정의한다.

3)결괏값을 좀 더 제한하기 위해 다양한 쿼리 옵션을 사용할 수 있다.

 

1.프로젝션(projections)

-결괏값 도큐먼트에 대해 반환할 필드를 지정하는 데 사용

 

-도큐먼트의 수가 많을 때 프로젝션을 사용하면 네트워크 지연과 역직렬화(desrialization)에 들어가는 비용을 줄일 수 있다.

 

-$slice 반환되는 도큐먼트의 부분집합을 선택한다.

 

프로젝션 예제

ex)

db.컬렉션이름.find({}, {'username': 1})

이 쿼리는 사용자 도큐먼트에서 username 필드와 _id 필드만을 반환한다. _id 필드는 특별 케이스로서 디폴트로 항상 포함된다.

 

필요없는 데이터들을 배제하기 위해서 필드 이름에 0을 지정한다.

 

ex)

db.컬렉션이름.find({}, {'addresses': 0, 'payment_methods': 0})

 

배열의 값을 어떤 범위 내에서 정할 수도 있다.

ex)

db.컬렉션이름.find({}, {'reviews': {$slice: 12}}) //처음 12개의 리뷰만 가져온다.

 

ex)

db.컬렉션이름.find({}, {'reviews': {$slice: [24,12]}})

// skip과 limit를 나타내는데, 처음 24개의 리뷰를 제외하고 난 후 가져올 리뷰를 12개로 제한하는 쿼리이다.

 

ex)

db.컬렉션이름.find({}, {'reviews': {'$slice': [24,12]}, 'reviews.rating': 1})

//처음 24개의 리뷰를 제외하고 난 후 가져올 리뷰를 12개로 제한하며, 리뷰의 평점만 포함시키도록 하는 쿼리.

 

2.정렬

-쿼리의 결과를 하나 혹은 그 이상의 필드에 대해 오름차순 or 내림차순으로 정렬할 수 있다.

 

ex)

db.컬렉션이름.find({}).sort({'rating':=1})

//리뷰를 평점이 높은 것부터 낮은 것까지 내림차순 정렬하는 쿼리

 

ex)

db.컬렉션이름.find({}).sort({'helpful_votes':-1, 'rating': -1})

//추천수와 평점순으로 내림차순 정렬하는 쿼리, 순서가 중요하다.

 

3.skip과 limit

-데이터가 대량일 경우 skip에 큰 값을 넘겨주게 되면(10,000이상), skip의 값만큼 도큐먼트를 스캔해야 하므로 비효율적이 될 수 있다.

 

-좀 더 나은 방법은 skip을 생략하고 대신 쿼리에 다음 결괏값이 시작되는 것을 나타내는 범위 조건을 추가하는 것이다.

ex)

db.docs.find({}).skip(500000).limit(10).sort({date: -1})

->

previous_page_date = new Date(2013, 05, 05)

db.docs.find({'date': {'$gt': previous_page_date}}).limit(10).sort({'date': -1})

 

 

728x90

댓글