본문 바로가기
NoSQL

MongoDB - Querying

by Mi.Ro 2023. 8. 7.

Querying

Quering for documents

  • find(), findOne()

      > db.c.find({}), db.c.find() -> collection c 내부 모든 것을 찾음

  • predicates : $and, $or

      > db.c.find({name : "Kim"})   -> name이 Kim인 document를 찾음

      > db.c.find({name : "Kim", age : 10})   -> name이 Kim이고 age가 10인 document를 찾음(logical and)

      > db.c.find({$and : [{name:"Kim"}, {age:10}]})   -> name이 Kim이고 age가 10인 document를 찾음

      > db.c.find({$or : [{name:"Kim"}, {age:10}]})   -> name이 Kim이거나 age가 10인 document를 찾음

      > db.c.find({name:"Kim", name:"Lee"})   -> name이 Lee인 사람만 찾음(name:"Kim" 무시)

Conditional quaries

  • 비교연산자 : $gt(greater than), $lt(less than), $gte(greater than equal), $lte(less than equal)

      > db.c.find({age : {$lt : 10}})   -> age가 10보다 작은 document 찾음

      > db.c.find({age : {$gte : 10, $lte : 20}})   -> age가 10보다 크거나 같고 20보다 작거나 같은 document 찾음

  •  $eq(equal), $ne(not equal), $in, $nin(not in)

      > db.c.find({age : {$ne : 10}})   -> age가 10과 같지 않음

      > db.c.find({age : {$in : [10, 20]}})   -> age가 10또는 20중에 있는 것 찾음

  • $mod, $not

      > db.c.find({age : {$mod : [2, 1}})   -> 나머지를 찾음

Projection

  • find()의 두번째 argument로 필요한 field만 projection함

      > db.c.find({name : 'Kim'}, {age:1, _id:0})   -> age field를 보여주고 _id는 안보여줌(선택 안할시 default로 보여줌)

Null, Exists

  • Null : not existing 의미

      > db.c.insertOne({A : null}}) 

      > db.c.insertOne({B : 'C'}})

      > db.c.find({A : null})  -> 위 두개가 다 나옴

      > db.c.find({A : {$eq : null}}) -> 위 두개가 다 나옴

      > db.c.find({A : {$exists : false}}) -> {B : 'C'}가 나옴. A라는 field가 없는 것

      > db.c.find({A : {$exists : true}}) -> {A : null}이 나옴. A라는 field가 있는 것

Regular expression

  • /letter/, /^letter/, /letter%/, /letter/i, /l.tter/, /l.*r/

      > db.c.insertOne({A:'Abcd'})

 

      > db.c.find({A : {$regex : /bc/}}) -> bc를 substring으로 가지고 있는지(regular expression 사용) (O)

      > db.c.find({A : /bc/ }) -> bc를 substring으로 가지고 있는것 (O)

      > db.c.find({A : /^bc/ }) -> bc를 prefix로 가지고 있는것 (X)

      > db.c.find({A : /bc%/}) -> bc를 suffix로 가지고 있는것 (X)

      > db.c.find({A : /abc/i }) -> case insensitive (O)

      > db.c.find({A : /A.cd.}) -> .은 any single letter를 의미 (O)

      > db.c.find({A : /A.d/}) -> (X)

      > db.c.find({A : /A.*d/}) -> *은 0 or more letter (O)

Querying arrays

  • inclusion, exact match, $all, $size

      > db.c.insertOne({_id : 1, A : ['a', 'b', 'c', 'd']})

      > db.c.insertOne({_id : 2, A : ['a', 'c', 'd', 'e']})

      > db.c.insertOne({_id : 3, A : 'a'})     

 

      > db.c.find({A : 'a'})  -> 3개 모두 출력(inclusion)

      > db.c.find({A: [a, b]}) -> 아무것도 출력 안됨(exact match)

      > db.c.find({A: {$all : [a, b]}}) -> 맨 위 출력(inclusion)

      > db.c.find({A : {$size : 4}}) -> 위 2개 출력 (개수)

 

      > db.c.find({"A.1" : 'b'})  -> 맨 위 출력(A의 1번째가 b인것 찾기)

 

      > db.c.find({A : ['a', 'b', 'd', 'c']})  -> 아무것도 안나옴(순서 중요)

      > db.c.find({A : 'a', A: 'e'})  -> 두번째 문서만 출력(첫번째 조건은 무시됨)

 

  • $slice : array elements를 slicing하는 projection operator

      > db.c.insertOne({_id : 1, A : [1, 2, 3, 4, 5, 6]})

 

      > db.c.find({_id : 1},{ A : {$slice : 2}}) -> _id, A:[1,2] 출력

      > db.c.find({_id : 1},{ A : {$slice : -2}}) -> _id, A:[5,6] 출력

      > db.c.find({_id : 1},{ A : {$slice : [1,3]}}) -> _id, A:[2,3,4] 출력 (1만큼 skip하고 그 뒤 3개 보여줌)

      > db.c.find({_id : 1},{ A : {$slice : [1,12]}}) -> _id, A:[2,3,4,5,6] 출력 (1만큼 skip하고 그 뒤 12개(모두) 보여줌)

      > db.c.find({_id : 1},{ A : {$slice : [12,1]}}) -> _id, A:[] 출력 (12만큼 skip(모두 skip)하고 그 뒤 1개 보여줌)

 

  • $slice를 $push 내에서 사용하기($each 사용 필수)

      > db.c.insertOne({_id : 5, A : [1, 2, 3, 4, 5, 6]})

 

      > db.c.update({_id : 5}, {$push:{A:{$each:[7,8,9,10,11], $slice:8}}}) -> A:[1,2,3,4,5,6,7,8] 출력 (8개까지만 push됨)

      > db.c.update({_id : 5}, {$push:{A:{$each:[7,8,9,10,11], $slice:-8}}}) -> A:[4,5,6,7,8,9,10,11] 출력 (뒤에서 8개까지만 push됨)

Positional projection

  • Positional operator : $

      > db.c.insert({A : ['a', 'b', 'c']})

      > db.c.find({A : 'a'}, {'A.$':1}) -> A:['a'] 만 나옴

Range queries

  • $gt:num1, $lt:num2 -> num1과 num2 사이 range 출력

      > db.c.find({age:{$gt:20, $lt:40}}) -> age:30만 출력

      

      > db.c.insertMany([{age : [15, 25]}, {age: [19, 21]}])

      > db.c.find({age:{$gt:20, $lt:40}}) -> 둘 다 출력(하나만 만족해도 출력)

 

      > db.c.insertMany([{age : [15, 25]}, {age: [19, 21]}])

      > db.c.find({age:{$elemMatch:{$gt:20, $lt:40}}}) -> age:[15,25]만 출력 (동시에 두 조건 다 만족)

Embedded field query

  • dot(.) notation 사용

      > db.c.find({"name.first" : "A", "name.last" : "B"}) 

Limits, skips, sorts

      > db.c.find({age:10}).limit(3)  -> 앞 3개만 출력

      > db.c.find({age:10}).skip(3)  -> 3개 skip

      > db.c.find({age:10}).sort({_id:1})   -> _id로 sort (-1이면 descending)

      > db.c.find({age:10}).count()   ->  개수 세기

 

      > db.c.find().skip(2).limit(4).sort({_id:1})  -> sort->skip->limit 순서로 함

Cursor, iteration

  • find()의 결과는 cursor로 access됨
  • iteration with cursor

      > var cursor = db.c.find()  -> local variable로 저장
      > while (cursor.hasNext()) { x = cursor.next(); print(x._id); printjson(x) }

  • iteration with forEach()

      > var cursor = db.c.find()  -> local variable로 저장
      > cursor.forEach( function(doc) { print(doc._id); printjson(doc)} )

  • iteration with map()

      > var cursor = db.c.find()  -> local variable로 저장
      > cursor.map( function(doc) { return doc._id })  -> 결과값 array로 return

'NoSQL' 카테고리의 다른 글

MongoDB - Geospatial data  (0) 2023.08.08
MongoDB - Indexing  (0) 2023.08.07
MongoDB - Crud operations  (0) 2023.08.07
MongoDB 기본 및 시작하기  (0) 2023.08.06
About NoSQL  (0) 2023.08.06