728x90

mongo를 쓰다보면,

list내에서 특정 값 혹은 document를 제거해야되는 경우가 굉장히많다.

 

이때는, 원본 자료를 불러와 해당 값을 제거한뒤 업데이트 시키는 방법 (덮어씌우기)을 주로 이용했다.

 

그런데, 자료를 불러올 필요가 없는 상황에서 해당 값만 바로 제거할수는 없을까? 하는 생각이 들었다.

찾아보니, 이때는  $pull 키워드로 해당 작업이 가능하다.

늘상 써오던 $set과 크게 다르지 않다

 

간단한 예제와 함께 포스팅을 마무리하기겠다.

// collection 이름이 Orders인 경우

Orders = [ 
  {
    _id: ...,
    menus: ['coffee', 'tea'],
  },
  {
    _id: ...,
    menus: ['bread', 'tea'],
  },
  {
    _id: ObjectId('abc'),
    menus: ['coffee', 'fruit'],
  },
];

// 특정 대상에 대한 처리 - ObjectId('abc')의 fruit을 제거할때
db.Orders.findOneAndUpdate({ _id: ObjectId('abc') }, { $pull: { menus: { $in: ['fruit']} }  })

// 전체 대상에서 fruit을 제거
db.Orders.updateMany({}, { $pull: { menus: { $in: ['fruit'] } } })


menu가 document형태로 들어가있을 경우?
Orders = [ 
  {
    _id: ...,
    menus: [
      {
        _id: ...,
        name: 'coffee',
        price: 100,
      },
      {
        _id: ...,
        name: 'tea',
        price: 200,
      }
    ],
  },
  {
    _id: ...,
    menus: [
      {
        _id: ...,
        name: 'bread',
        price: 150,
      },
      {
        _id: ...,
        name: 'tea',
        price: 200,
      }
    ],
  },
  {
    _id: ObjectId('abc'),
    menus: [
      {
        _id: ...,
        name: 'coffee',
        price: 100,
      },
      {
        _id: ...,
        name: 'fruit',
        price: 500,
      }
    ],
  },
];

// 특정 대상에 대한 처리 - ObjectId('abc')의 fruit을 제거할때
db.Orders.findOneAndUpdate({ _id: ObjectId('abc') }, { $pull: { menus: { name: 'fruit' } }  })

// 전체 대상에서 fruit을 제거
db.Orders.updateMany({}, { $pull: { menus: { name: 'fruit' } } })

 

 

[참고자료]

docs.mongodb.com/manual/reference/operator/update/pull/

728x90
반응형