본문 바로가기

mongoDB

[mongoDB] Operations

반응형

updating...

  Query and Projection Operators  

Query Selectors 

$eq ( = equal ) 같은 value
$gt ( < greater than ) ~보다 큰 value
$gte ( <= greater than or equal ) ~보다 크거나 같은 value
$in ( in an array ) 주어진 배열의 요소들 중 하나라도 일치하는지
  favouriteFoods = [ 'a', 'b', 'c' ] 인 경우 
Model.find({ favouriteFood: 'a' }, ... ); 요렇게 하면 자동으로 배열 안의 요소가 있다면 ~ filter가 됨
$lt ( > less than ) ~보다 작은 value
$lte ( >= less than or equal) ~보다 작거나 같은 value
$ne ( not equal ) ~와 같지 않은 value
$nin ( not in an array ) 주어진 배열 요소들 중 하나라도 일치하지 않는 경우

Logical 

$and 여러 경우를 모두 포함한 경우
$not  ~ 가 아닌 ( 해당 조건의 field가 없는 곳까지 모두 반환 ) 
  db.inventory.find( { price: { $not: { $gt: 1.99 } } } )

-> 이 경우 lte operater를 쓰는 것과 조금 다르다. 

{ $not: { $gt: 1.99 }} price필드가 1.99보다 작거나 같은 곳 또는 price field가 존재하지 않는 데이터도 반환한다.
{ $lte: 1.99 } 를 쓰면 price 필드가 존재하는 곳만 오직 반환한다. 
$nor 모든 경우를 fail한 경우 
  { $nor: [ {  }, {  }, ...  {  } ] }
$or 여러 경우 중 하나라도 맞는 경우

Element

$exists 특정한 field가 있는지 확인
  { field: { $exists: <boolean> } }

true : 해당 field를 가지고 있는 도큐먼트들을 찾는다.  * null값도 모두 포함 
false : 해당 field를 가지고 있지 않은 도큐먼트 찾는다.
$type 주어진 타입의 필드를 선택 
  { field: { $type: <BSON type> } }
{ field: { $type: [ <BSON type1> , <BSON type2>, ... ] } }

The above query will match documents where the field value is any of the listed types. The types specified in the array can be either numeric or string aliases.

Evaluation

$expr 쿼리 언어 안에서 집합 (aggregation) 표현을 사용할 수 있도록 한다. 
  { $expr: { <expression> } }
$mod  

Geospatial

   
   

Array

   
   

Bitwise

   
   
   

Projection Operators

   
   

 

 

 

  Update Operators  

fields

$currentDate field의 value를 현재 date로 설정 ( either as a Date or a Timestamp )
  { $currentDate: { <field1>: <typeSpecification1>, ... } }

소문자 "date", "timestamp" 로만 가능 
$inc 해당 field의 수를 주어진 수만큼 증가시킨다. 
 
{ $inc: { <field1>: <amount1>, <field2>: <amount2>, ... } }

예시 1. 
주어진 데이터 : { _id: 1, qt: 10, metrics: { orders: 2 } } 

실행할 쿼리 : 
db.products.update(
   { _id: 1 },
   { $inc: { qt: -2, "metrics.orders": 1 } }
)

결과 : 
 { _id: 1, qt: 8, metrics: { orders: 3 } } 

$min 존재하는 field value보다 주어진 value가 더 적은 경우에만 field를 주어진 value로 업데이트 한다. 
 
{ $min: { <field1>: <value1>, ... } }

예시 1.
주어진 데이터 : { _id: 1, highScore: 800, lowScore: 200 } 

db.scores.update( { _id: 1 }, { $min: { lowScore: 150 } } ) 이렇게 처리하면
{ _id: 1, highScore: 800, lowScore: 150 } 150이 더 작기때문에 150으로 업데이트된다. 

$max 주어진 value가 존재하는 value보다 더 큰 경우에만 field의 값을 주어진 value로 업데이트 한다. 
 
{ $max: { <field1>: <value1>, ... } }

예시 1.
주어진 값 : { _id: 1, highScore: 800, lowScore: 200 }
 
아래의 쿼리를 실행 : 
db.scores.update( { _id: 1 }, { $max: { highScore: 950 } } )

결과 : 
{ _id: 1, highScore: 950, lowScore: 200 } -> 950보다 800이 작으므로 주어진 950으로 수정된다. 

예시 2.
주어진 값 : { _id: 1, highScore: 950, lowScore: 200 }

db.scores.update( { _id: 1 }, { $max: { highScore: 870 } } )
{ _id: 1, highScore: 950, lowScore: 200 }.  -> 870보다 크면 데이터 변화가 없다. 

$mul 주어진 수와 해당 field의 값을 곱한 값으로 update한다. 
해당 field는 반드시 숫자 numeric 값을 가져야 한다. 
 
{ $mul: { <field1>: <number1>, ... } }

예시 1. 
주어진 데이터 : { "_id" : 1, "item" : "ABC", "price" : NumberDecimal("10.99"), "qty" : 25 }
* numberSigned = 숫자+부호
* numberDecimal = 숫자+부호+소수점

아래의 쿼리 실행 : 
db.products.update(
   { _id: 1 },
   { $mul: { price: NumberDecimal("1.25"), qty: 2 } }
)    

결과 : 
{ "_id" : 1, "item" : "ABC", "price" : NumberDecimal("13.7375"), "qty" : 50 }

예시 2. 
없는 field를 쓰는 경우 해당 field값이 생긴다. 
주어진 데이터 : { _id: 2,  item: "Unknown" }

아래의 쿼리 실행 : 
db.products.update(
   { _id: 2 },
   { $mul: { price: NumberLong(100) } }
)

결과 : 

{ "_id" : 2, "item" : "Unknown", "price" : NumberLong(0) }
$rename field의 이름을 수정한다. 
 
$rename: { <field1>: <newName1>, <field2>: <newName2>, ... } }

예시 1. 
db.students.updateMany( {}, { $rename: { "nmae": "name" } } )

$set 도큐먼트의 해당 필드의 value만 변경 
$setOnInsert upsert: true의 경우 데이터가 있다면 modify, 없다면 insert가 된다. insert 하는 경우에만 해당 field와 value를 넣는다. (최초 insert에만 작동)
 
$set, $setOnInsert 예시 1.

const function = _.map(itemsArray, ({ a, b, c }) => {
   return {
      updateOne: {
          filter: { a, b },
          update: { $setOnInsert: { a, b }, $set: { c } },
          upsert: true,
      },
   };
});

a와 b의 값이 일치하는 곳에 update 내용을 업데이트 한다. upsert : true => 해당 값이 없으면 새로  insert한다. insert할 때 a,b 값은 최초이자 마지막으로 넣는다. 이후 수정될 때는 c만 수정된다. 

$unset 도큐먼트의 특정 field를 제거한다. 
 
* 만약 배열의 요소와 쓰이게 되면 배열 요소를 아예 제거하기보다 null로 변경하여 배열의 크기와 요소의 위치를 유지시킨다. 

Array Update Operators

$ 쿼리문과 일치하는 첫번째 요소를 업데이트하는 placeHolder로써의 역할을 한다. 
$[] 쿼리문과 일치하는 도큐먼트의 배열 안 모든 요소들을 업데이트하는 placeHolder로써의 역할을 한다. 
$[<identifier>] 쿼리문과 일치하는 도큐먼트의 arrayFilters condition에 맞는 모든 요소들을 업데이트하는 placeHolder로써의 역할을 한다. 
 
  • To project, or return, an array element from a read operation, see the $ projection operator instead.
  • To update all elements in an array, see the all positional operator $[] instead.
  • To update all elements that match an array filter condition or conditions, see the filtered positional operator instead $[<identifier>].
$addToSet 오직 set안에 존재하지 않는 경우에만 요소를 배열에 추가한다. 존재하는 경우 아무 일도 일어나지 않는다. 
Adds elements to an array only if they do not already exist in the set.
 
{ $addToSet: { <field1>: <value1>, ... } }

예시 1 .
주어진 값 
{ _id: 1, colors: "blue,green,red" }  ----> [] 배열이 아니므로 실패한다. 

예시 2. 
주어진 값 
{ _id: 1, letters: ["a", "b"] }

실행 쿼리 : 
db.test.update(
   { _id: 1 },
   { $addToSet: { letters: [ "c", "d" ] } }
)

결과 : 
{ _id: 1, letters: [ "a", "b", [ "c", "d" ] ] }

예시 3. ** 해당 배열에 요소 하나씩 추가하고 싶을 때 
주어진 값 : 
{ _id: 2, item: "cable", tags: [ "electronics", "supplies" ] }

실행 쿼리 : 
db.inventory.update(
   { _id: 2 },
   { $addToSet: { tags: { $each: [ "camera", "electronics", "accessories" ] } } }
 )

결과 : 
{
  _id: 2,
  item: "cable",
  tags: [ "electronics", "supplies", "camera", "accessories" ]
}

$pop 배열의 첫번째 또는 마지막 요소를 제거한다. 
-1 이면 첫번째 요소 제거
  1 이면 마지막 요소 제거 
 
{ $pop: { <field>: <-1 | 1>, ... } }

예시 1. 
주어진 값 : 
{ _id: 1, scores: [ 8, 9, 10 ] }

실행 쿼리 : 
db.students.update( { _id: 1 }, { $pop: { scores: -1 } } )

결과 : 

{ _id: 1, scores: [ 9, 10 ] }

$pull  특정 조건에 맞는 값 / 값들의 배열로부터 제거한다. by ** 특정 쿼리 ($pullAll은 특정 values로 제거) 
 
{ $pull: { <field1>: <value|condition>, <field2>: <value|condition>, ... } }

예시 1. 
주어진 값 : 
{
   _id: 1,
   fruits: [ "apples", "pears", "oranges", "grapes", "bananas" ],
   vegetables: [ "carrots", "celery", "squash", "carrots" ]
}
{
   _id: 2,
   fruits: [ "plums", "kiwis", "oranges", "bananas", "apples" ],
   vegetables: [ "broccoli", "zucchini", "carrots", "onions" ]
}

실행 쿼리 : 
db.stores.update(
   {},
   $pull: { fruits: { $in: ["apples", "oranges"] }, vegetables: "carrots" }},
   { multi: true }
)

예시 2.
주어진 값 : 
{ _id: 1, votes: [ 3, 5, 6, 7, 7, 8 ] }

실행 쿼리 : 
db.profiles.update( { _id: 1 }, { $pull: { votes: { $gte: 6 } } } )

결과 : 
{ _id: 1, votes: [  3,  5 ] }

$push 배열에 요소를 추가한다.  
* addToSet과 다른 점은 addToSet은 배열 안에 추가하려는 요소가 존재하지 않을 때만 추가하는 것 같다
* 아래 modifies들과 함께 쓰인다. 
$each
$slice
$sort
$position
 
{ $push: { <field1>: <value1>, ... } }

예시 1.  - 요소 1개 추가 시
db.students.update(
   { _id: 1 },
   { $push: { scores: 89 } }
)

예시 2. - 요소 2개 이상 추가 시 ($each사용) 
db.students.update(
   { name: "joe" },
   { $push: { scores: { $each: [ 90, 92, 85 ] } } }
)

$pushAll 특정 쿼리에 의해 요소들을 지우는 $pull과 다르게 $pullAll은 존재하는 배열의 특정한 값들을 values로 특정하여 모두 지운다. 
 
{ $pullAll: { <field1>: [ <value1>, <value2> ... ], ... } }

예시 1.
주어진 값 : { _id: 1, scores: [ 0, 2, 5, 5, 1, 0 ] }

실행 쿼리 : 
db.survey.update( { _id: 1 }, { $pullAll: { scores: [ 0, 5 ] } } )

결과 : 
{ "_id" : 1, "scores" : [ 2, 1 ] }

$each $addToSet 과 $push와 함께 쓰인다. 배열 안에 값들을 넣을 때 각각 요소로 넣어지게 하기 
* $addToSet은 해당 배열 안의 요소가 존재하면 명령이 무시된다. 즉, 배열 안 요소가 존재하지 않을 때만 값을 추가한다. 
* $push는 배열 안 요소들과 상관없이 그냥 추가한다. 
 
{ $addToSet: { <field>: { $each: [ <value1>, <value2> ... ] } } }
{ $push: { <field>: { $each: [ <value1>, <value2> ... ] } } }

예시 1.
주어진 값 : { _id: 2, item: "cable", tags: [ "electronics", "supplies" ] }

실행 쿼리 : 
db.inventory.update(
   { _id: 2 },
   { $addToSet: { tags: { $each: [ "camera", "electronics", "accessories" ] } } }
 )

결과 : *** 배열 안에 이미 존재하는 "electronics"는 중복 추가되지 않았다. 
{
  _id: 2,
  item: "cable",
  tags: [ "electronics", "supplies", "camera", "accessories" ]
}

$slice $push operation동안 배열 요소들의 수를 제한한다. 
$slice를 사용하기 위해 반드시 $each modifier와 함께 사용되어야 한다.  
빈 [] 배열을 $each에 보내면 $slice가 has an effect. (?) 무슨 내용인지 

To use the $slice modifier, it must appear with the $each modifier. You can pass an empty array [] to the $each modifier such that only the $slice modifier has an effect.
 
{
  $push: {
     <field>: {
       $each: [ <value1>, <value2>, ... ],
       $slice: <num>
     }
  }
}

<num> 은 아래와 같다. 
1. 0 (zero) - [] 빈 배열로 업데이트 할 때
2. 음수 - 마지막 num개의 요소들만 업데이트 할 때
3. 양수 - 첫번째부터 num개의 요소들만 업데이트 할 때

예시 1.
주어진 값 : 
{ "_id" : 1, "scores" : [ 40, 50, 60 ] }

실행 쿼리 : 
db.students.update(
   { _id: 1 },
   {
     $push: {
       scores: {
         $each: [ 80, 78, 86 ],
         $slice: -5
       }
     }
   }
)

결과 : *** 끝에서 5개의 요소들만 남음 $slice: 5였다면 [40, 50, 60, 80, 78] 이 나옴 
{ "_id" : 1, "scores" : [  50,  60,  80,  78,  86 ] }

$sort $push operation동안 배열의 요소들을 정렬시킨다. 
$sort 를 쓰기 위해서는 반드시 $each와 함께 써야한다.
You can pass an empty array [] to the $each modifier such that only the $sort modifier has an effect.
 
{
  $push: {
     <field>: {
       $each: [ <value1>, <value2>, ... ],
       $sort: <sort specification>
     }
  }
}

<sort specification> 
1 : 오름차순
-1: 내림차순 

예시 1.
주어진 값 : 
{
  "_id": 1,
  "quizzes": [
    { "id" : 1, "score" : 6 },
    { "id" : 2, "score" : 9 }
  ]
}

실행 쿼리 : 
db.students.update(
   { _id: 1 },
   {
     $push: {
       quizzes: {
         $each: [ { id: 3, score: 8 }, { id: 4, score: 7 }, { id: 5, score: 6 } ],
         $sort: { score: 1 }
       }
     }
   }
)

결과 : 
{
  "_id" : 1,
  "quizzes" : [
     { "id" : 1, "score" : 6 },
     { "id" : 5, "score" : 6 },
     { "id" : 4, "score" : 7 },
     { "id" : 3, "score" : 8 },
     { "id" : 2, "score" : 9 }
  ]
}

 
   
   
   
   
   
   

Bitwise

   

 

 

Query Modifier 

$comment query에 코멘트 붙이기
v3.2부터 앤안쓰지만 mongosh에서 이제 cursor.coment()로 변경됨
  db.collection.find()._addSpecial("$comment", '코멘트' )
db.collection.find().comment( '코멘트' )
db.collection.find({ $query: {}, $comment: '코멘트' } )
$explain 쿼리에 대한 정보를 제공한다. 

v3.2부터 사라졌으나 cursor.explain()으로 사용 가능하다. 
  db.collection.find()._addSpecial('$explain', 1)
db.collection.find({ $query: {}, $explain: 1 })
$hint $hint()는 쿼리를 이행하기위해 query optimizer가 특정한 인덱스를 사용하도록 한다.
v3.2부터 사용하지 않지만 mongosh에서 cursor.hint()로 사용가능하다. 
  db.users.find().hint({ age: 1 })
db.users.find( { $query: {}, $hint: { age: 1 }})
$max 최대값을 정한다.
v3.2부터 사용하지 않으나 mongosh에서는 cursor.max()를 사용한다. 
  db.collection.find( { subject: 'asdf' } ).max( { age: 100} ).hint( { age: 1 } )
$maxTimeMS 쿼리가 처리되는 시간을 특정하여 해당 값 이내로 끝나도록 한다. 이후의 시간이 소요되면 time limit 에러가 난다. 
v3.2부터 사용하지 않으나 mongosh에서는 cursor.maxTimeMS()를 사용한다. 
  db.collection.find().maxTimeMS(100)
db.collection.find({$query: {}} )
db.collection.find({}))._addSpectial(400)
$min 최소값을 정한다.
v3.2부터 사용하지 않으나 mongosh에서는 cursor.min()를 사용한다. 
  db.collection.find().min( {age: 20} ).max( {age: 25} ).hint( {age: 1} )
$orderby 결과값들을 오름차순 or 내림차순으로 나타낸다. 
v3.2부터 사용하지 않으나 mongosh에서는 cursor.max()를 사용한다.  
  mongosh에서는 db.collection.find().sort( { age: -1 } ) 와 같이 cursor.sort() 매서드도 존재한다. 만약 옵션으로 특정하고 싶다면 $orderby를 쓰면 된다. 

db.collection.find().addSpecial('orderby', { age: -1 })
db.collection.find( {$query: {}, $orderby: { age: -1 } } )
$query $query는 MongoDB가 해당 표현을 query로써 이해하도록 만든다.
v3.2부터 사용하지 않으나 mongosh에서는 cursor.query()를 사용한다.  
  db.collection.find( { $query: { age: 25} } } )
=== db.collection.find( {age: 25 })
$returnKey 오직 index field or 쿼리의 결과에 대한 fields만을 반환한다. 
returnKey가 true로 설정되어 있고 index를 사용하지 않고 read해오면 반환값은 어떠한 fields도 가지고 있지 않을 것이다. 
v3.2부터 사용하지 않으나 mongosh에서는 cursor.returnKey()를 사용한다.  
  db.collection.find( { <query> } )._addSpecial( "$returnKey", true)
db.collection.find( { $query: { <query> }, $returnKey: true } )
$showDiskLoc $showDiskLoc 옵션은 $diskLoc 이라는 필드를 반환 도큐먼트에 더한다. 더해진 요 diskLoc 필드는 또 하나의 도큐먼트인데 이는 dis location 디스크 위치 정보를 지니고 있다. 
v3.2부터 사용하지 않으나 mongosh에서는 cursor.showDiskLoc()을 사용한다.  
  db.collection.find().showDiskLoc()
db.collection.find( { <query> } )._addSpecial('$showDiskLoc', true)
db.collecion.find( { $query: { <query> } , $showDiskLoc: true } ) 
$natural  ----> cursor.hint() 를 사용하세요 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

반응형