본문 바로가기
DataBase/NoSQL

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

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

#셀렉터 매칭

-가장 간단한 쿼리는 키-값 쌍이 도큐먼트에 문자적으로 일치하는 셀렉터를 사용하는 쿼리다.

ex)

db.컬렉션이름.find({"키":"값"})

db.컬렉션이름.find({"키1":"값1","키2":"값2"})

 

-하나 이상의 키 값을 넘겨줄 때는 조건이 모두 매치되어야 한다.(쿼리 조건 함수는 논리적 AND)

 

-MongoDB에서 모든 텍스트 문자열 일치는 대소문자를 구분한다.(Case sensitive)


#범위

연산자 범위 해당하는 연산자
$lt ~보다 작은 <
$gt ~보다 큰 >
$lte ~보다 작거나 같은 <=
$gte ~보다 크거나 같은 >=

ex)

db.컬렉션.find({'birth_year': {'gte': 1985}, 'birth_year': {'$lte': 2015}})

위의 쿼리는 1985년보다 크거나 같고 2015년보다 작거나 같은 생일을 찾는 쿼리가 아니다.

->

db.컬렉션.find({'birth_year': {'gte': 1985', '$lte': 2015}})

처럼 바꾸어야 알맞는 쿼리가 된다.

 

ex)

db.컬렉션이름.find({'value': {'$gte': 97}})

위의 쿼리는 벨류 키의 값이 97이상인 값들을 반환하는데, 문자인 a,b,c와 같은 값들이 ascii값으로 반환되는 것이 아니라, 문자로 인식되므로 정숫값을 가진 도큐먼트만 반환된다.

 

db.컬렉션이름.find{'value': {'$gte': "a"}})

위와 같은 쿼리를 써야 문자열로 결과를 얻을 수 있다.


#집합 연산자

-$in, $all, $nin 같은 세 개의 연산자는 연산자에 대한 predicate로 하나 혹은 그 이상의 값의 리스트를 받으며, 집합 연산자라 불린다.

연산자 설명
$in 어떤 인수든 하나라도 참고 집합에 있는 경우 일치
$all 모든 인수가 참고 집합에 있고 배열이 포함된 도큐먼트에서 사용되는 경우 일치
$nin 그 어떤 인수도 참고 집합에 있지 않을 경우 일치

-$in 연산자는 하나의 속성에 대해 일종의 논리합(Boolean Inclusive OR)으로 볼 수 있다.

 

-$in 연산자는 ID리스트와 함께 자주 쓰인다.

 

-$nin은 일치되는 것이 없는 도큐먼트를 찾아 준다.

 

-$all은 해당 조건이 검색 키와 일치하는 도큐먼트를 찾아 준다.(배열로 저장되어 있어야 의미가 있다.)

 

-선택성(selectivity)은 인덱스를 사용하여 결과의 범위를 좁히는 쿼리문이다.

1)$ne 와 $nin 연산자는 선택적이지 않다.

2)집합 연산자를 사용할 때 $in과 $all은 인덱스를 이용하지만, $nin은 인덱스를 사용할 수 없으므로 컬렉션을 스캔해야 한다.

3)$nin을 사용해야 한다면 인덱스를 사용하는 다른 검색어와 조합해서 사용하는 것이 좋다.


#부울 연산자

-MongoDB의 논리적 연산자로는 $ne, $not, $or, $and, $nor, $exists가 있다.

연산자 설명
$ne 인수가 요소와 같지 않은 경우 일치
$not 일치 결과를 반전시킴(반대로 만듦)
$or 제공된 검색어 집합 중 하나라도 TRUE인 경우 일치
$nor 제공된 검색어 집합 중 그 어떤 것도 TRUE가 아닌 경우 일치
$and 제공된 검색어 집합이 모두 TRUE인 경우 일치
$exists 요소가 도큐먼트 안에 존재할 경우 일치

-같지 않음(not equal to)을 의미하는 $ne 연산자는 최소한 하나 이상의 다른 연산자와 조합해서 사용하면 가장 좋다.

ex)

db.컬렉션이름.find({'details.manufacturer': 'Acme', tag: {$ne: "gardening"} })

 

-$ne는 키 값이 단일한 값이거나 배열인 경우 모두 수행된다.

 

-$ne는 지정한 값이 아닌 경우를 찾아 주지만, $not 연산자는 MongoDB의 다른 연산자나 정규 표현식 쿼리로부터 얻은 결과의 여집합을 반환한다.

ex)

db.컬렉션이름.find({'age': {'$not': {'$lte': 30}}})

-> 나이가 30보다 큰 도큐먼트만 반환한다.

 

-$or 연산자는 두 개의 서로 다른 키에 대한 논리합을 표현한다.

ex)

db.컬렉션이름.find({'details.color': {$in: ['blue','Green']}})

같은 키 내에서 찾을때는 $in을 사용한다.

 

ex)

db.컬렉션이름.find({

     '$or': [

           {'details.color': 'blue'},

           {'details.manufacturer': 'Acme'}

         ]

})

다른 키 인 조건에 해당하는 것들을 모두 찾기 위해서는 $or사용

 

-$or 연산자는 쿼리 셀렉터의 배열을 취하는데, 여기서 각 셀렉터는 애드혹 쿼리가 될 수 있고 다른 연산자를 포함할 수도 있다.

 

-$nor는 $or와 거의 동일하게 작동하지만, 어떤 쿼리 셀렉터도 TRUE가 아닌 경우에만 논리적으로 TRUE이다.

 

-$and 연산자도 질의 셀렉터의 배열을 취한다.

ex)

db.컬렉션이름.find({

      $and: [

           {

              tags: {$in: ['git','holiday']}

           },

           {

              tags: {$in: ['gardening','landscaping']}

           }

        ]

})

두 개의 $in쿼리를 $and 쿼리로 연결 할 수 있다.


#특정 키로 도큐먼트에 질의하기

-$exists는 특정 키를 가지고 있는지 질의할 때 사용

ex)

db.컬렉션이름.find({'details.color': {$exists: false}})

색상 속성을 갖고 있지 않는 도큐먼트를 찾는 쿼리

 

ex)

db.컬렉션이름.find({'details.color': {$exists: true}})

색상 속성을 갖고 있는 도큐먼트를 찾는 쿼리


#서브도큐먼트 매칭

-임베디드 객체를 가리키는 키를 가지는 경우도 있다.

ex)

details 속성

 

{

   _id: ObjectId("~~~"),

   slug: "~~~",

   sku: "~~~",

   details: {

     model_num: ~~~,

     manufacturer: "~~~",

     manufacturer_id: ~~~,

     color: "~~~"

 }

}

이렇게 임베디드된 객체에 대한 쿼리는 관련된 키를 .로 구분한다.

ex)

db.컬렉션이름.find({'details.manufacturer': "~~~"});


#배열

-문자열이나 객체ID 그리고 심지어는 다른 도큐먼트의 리스트를 저장하는 데 사용한다.

연산자 설명
$elemMatch 제공된 모든 조건이 동일한 하위 도큐먼트에 있는 경우 일치
$size 배열 하위 도큐먼트의 크기가 제공된 리터럴 값과 같으면 일치

ex)

{

   _id: ObjectId("~~~"),

   slug: "~~~",

   sku: "~~~",

   tags: ["tools", "equipment", "soil"]

}

-"soil"이라는 태그를 갖는 상품에 대해 질의하는 것은 간단하며, 하나의 도큐먼트 값에 대해 질의하는 것과 동일한 문법을 사용한다.

ex)

db.컬렉션이름.find({tags: "soil"})

 

-필드에 대한 인덱스를 이용할 수 있다.

ex)

db.컬렉션이름.ensureIndex({tags: 1})

 

-닷(dot)표기법을 써서 배열 내의 특정 위치에 있는 값에 대해 질의할 수 있다.

ex)

db.products.find({'tags.0': "soil"})

 

-서브도큐먼트의 배열로도 만들 수 있다.

ex)

{

   _id: ObjectID~~

   username: ~~~

   addresses: [

       {

             name: "home",

             street: "588 5th street",

             city: "brooklyn",

             state: "NY",

             zip: 11215

       },

       {

             name: "work",

             street: "1 E. 23rd Street",

             city: "New York",

             state: "NY",

             zip: "10010

       },

    ]

}

 

-여러 개의 조건을 하나의 서브 도큐먼트에 대해 제한하려면 $elemMatch 연산자를 쓰면 된다.

(서브도큐먼트에서 두 개 이상의 속성이 매치되는 것을 찾는 경우에만 사용된다.)

ex)

db.컬렉션이름.find({

   'addresses': {

       '$elemMatch': {

           'name': 'home',

           'state': 'NY'

          }

     }

})


#배열 크기별 질의

-$size 연산자는 배열의 크기에 대해 질의할 수 있다.

ex)

정확히 세 개의 주소를 가지고 있는 모든 사용자를 검색하려면 다음과 같이 사용

db.컬렉션이름.find({'addresses': {$size: 3}})

 


 

728x90

댓글