ETC

mongodb - $push와 $addToSet의 차이점

알쓸개잡 2024. 2. 18.

MongoDB에서 $push 연산자와 $addToSet 연산자는 Document의 배열 필드에 요소를 추가하는 데 사용되는 연산자다.

배열 필드에 요소를 추가하는 공통적인 동작을 수행하지만 $push와 $addToSet 에는 주요한 차이점이 있다.

 

$push 연산자

$push 연산자는 값이 배열에 이미 존재하더라도 지정된 값을 배열에 추가한다. 즉, 중복 체크를 수행하지 않고 중복 값을 허용한다.

{
  "_id": 1,
  "receiver": "receiver@test.com",
  "senders": ["sender1@test.com", "sender2@test.com"]
}

와 같은 Document에서 $push 연산자로 아래와 같이 요소를 추가한다.

db.senders.updateOne(
  { _id: 1 },
  { $push: { "senders": "sender3@test.com" } }
)

=========================================
업데이트 결과
{
  acknowledged: true,
  insertedId: null,
  matchedCount: 1,
  modifiedCount: 1,
  upsertedCount: 0
}

modifiedCount: 1의 결과로 문서에 변경이 되었음을 알 수 있다.

결과는 다음과 같다.

{
  "_id": 1,
  "receiver": "receiver@test.com",
  "senders": [
    "sender1@test.com",
    "sender2@test.com",
    "sender3@test.com"
  ]
}

여기서 "sender3@test.com" 동일한 요소를 다시 추가하면 결과는 다음과 같다.

{
  "_id": 1,
  "receiver": "receiver@test.com",
  "senders": [
    "sender1@test.com",
    "sender2@test.com",
    "sender3@test.com",
    "sender3@test.com"
  ]
}

 

$addToSet 연산자

$addToSet 연산자는 값이 배열에 존재하지 않는 경우에만 문서의 배열 필드에 값을 추가하여 중복된 값을 허용하지 않는다.

$push 연산자와 달리 $addToSet은 삽입하기 전에 중복 검사를 수행하여 중복 항목을 방지한다.

배열에 이미 값이 존재하는 경우에는 아무런 동작을 수행하지 않는다.

다음과 같은 Document의 상태에서

{
  "_id": 1,
  "receiver": "receiver@test.com",
  "senders": [
    "sender1@test.com",
    "sender2@test.com",
    "sender3@test.com"
  ]
}

"sender3@test.com" 동일한 요소를 다시 추가하면 결과는 다음과 같다.

db.senders.updateOne(
	{_id: 1}, 
    {$push: {"senders": "sender3@test.com"}}
)

============================================

업데이트 결과
{
  acknowledged: true,
  insertedId: null,
  matchedCount: 1,
  modifiedCount: 0,
  upsertedCount: 0
}

$push 예시와는 달리 업데이트 결과에 modifiedCount:0으로 중복 요소에 대해서는 추가를 수행하지 않음을 알 수 있다.

결과는 다음과 같다.

{
  "_id": 1,
  "receiver": "receiver@test.com",
  "senders": [
    "sender1@test.com",
    "sender2@test.com",
    "sender3@test.com"
  ]
}

 

db.senders.updateOne( 
  {_id: 1}, 
  {$addToSet: 
    {"senders": 
      { $each: ["sender3@test.com", "sender4@test.com"]}
    }
  }
)

======================================
수행 결과
{
  acknowledged: true,
  insertedId: null,
  matchedCount: 1,
  modifiedCount: 1,
  upsertedCount: 0
}

"sender3@test.com", "sender4@test.com" 배열을 각각의 요소로 senders 배열 필드에 추가하면 "sender3@test.com"은 제외하고 "sender4@test.com" 요소만 추가됨을 알 수 있다.

{
  "_id": 1,
  "receiver": "receiver@test.com",
  "senders": [
    "sender1@test.com",
    "sender2@test.com",
    "sender3@test.com",
    "sender4@test.com"
  ]
}

 

결론

$push 연산자는 중복된 데이터를 포함하여 배열에 데이터를 저장해야 하는 경우에 사용하고 $addToSet 연사자는 배열에 중복된 값 없이 고유한 데이터를 저장해야 하는 경우에 사용한다.

댓글

💲 추천 글