안녕하세요
MongoDB: $addToSet 중복되는 값을 배열에 추가할 때 본문
배열에 중복되는 값이 존재할 경우 추가하지 않고 싶다면: $addToSet
배열에 값을 추가할 때는 $push 연산자 말고도 $addToSet을 쓸 수 있습니다.
이름에서 알 수 있듯이 $addToSet은 중복을 허용하지 않습니다.
$addToSet 연산자를 사용하여 배열에 값을 추가할 때
해당 배열에 값이 이미 존재하는 경우 아무런 동작을 하지 않고,
배열에 값이 존재하지 않으면 새로운 값이 배열에 추가됩니다.
다음과 같은 컬렉션이 있다고 합시다.
{ _id: 1, number: ["one", "two", "three"] }
$addToSet 연산자를 사용하여 "one"을 추가하려고 하면 아무런 동작을 하지 않습니다.
db.collection.updateOne( { _id: 1 }, { $addToSet: { number: "one" } } )
배열 안에 존재하지 않는 "four"을 추가해봅시다.
db.collection.updateOne( { _id: 1 }, { $addToSet: { number: "four" } } )
위 코드를 실행하면, number 배열에 "four"이 추가됩니다.
$addToSet 연산자는 중복 값을 방지하기 때문에, 배열에 중복되지 않은 값을 추가할 때 사용하면 편리하다/
하지만, 객체는 추가 되는걸요? _id 가 매번 새로운 객체를 생성
addToSet을 이용할 때 위와 같은 배열에 단순 string을 담은 형태가 아니라,
{ number: ["one", "two", "three"] }
아래와 같이 객체를 추가하고 싶다면?
foundArray.addToSet(
{ number: 'one' },
{ number: 'two' },
{ number: 'three' }
);
처음에는 이렇게 추가가 잘 되는 듯 하다.
foundArray : [
{ _id: randomGeneratedId, number: 'one' },
{ _id: randomGeneratedId, number: 'two' },
{ _id: randomGeneratedId, number: 'three' }
]
다음으로 one을 제외하고 four, five가 추가되길 기대하면서 배열을 추가해보면?
foundArray.addToSet(
{ number: 'one' },
{ number: 'four' },
{ number: 'five' }
);
one이 그대로 추가가 되어버린다.
foundArray : [
{ _id: randomGeneratedId, number: 'one' },
{ _id: randomGeneratedId, number: 'two' },
{ _id: randomGeneratedId, number: 'three' },
{ _id: randomGeneratedId, number: 'one' },
{ _id: randomGeneratedId, number: 'four' },
{ _id: randomGeneratedId, number: 'five' }
]
one two three one two three를 추가해도 똑같이 있는 그대로 전부 추가가 되어버리는 결과가 나타날 것이다.
원인은 mogodb에서 자동으로 생성하는 _id 에 있다.
_id: ObjectId('63fb2aa03852bcd628bf6007)
위와 같은 랜덤한 id가 생성이 되면서
새롭게 update할 요소는 중복되지 않은 새로운 요소로 처리가 되는 것이다.
새롭게 update할 요소는 중복되지 않은 새로운 요소로 처리가 되는 것이다.
해결방법
Mongoose의 schema를 _id: false 로 지정하거나
const citiesObjSchema = new mongoose.Schema({ key: Number, name: String, _id: false,});
_id fileds 를 직접(중복되지 않는 값으로) 정해주면 된다.
$addToSet: {
videoArray: {
_id: playlistItem.snippet.resourceId.videoId,
publishedAt: playlistItem.snippet.publishedAt,
title: playlistItem.snippet.title,
description: playlistItem.snippet.description,
thumbnailsUrl: playlistItem.snippet.thumbnails.high.url,
},
},
'유튜브컨텐츠탐색-StelLife > MongoDB' 카테고리의 다른 글
Promise.all 여러개의 프로미스를 병렬로 실행한 결과를 배열로 반환 (Promise.allSettled) (0) | 2023.03.06 |
---|---|
for문 data부르기 error는 try-catch로 넘어가기, bulkwrite (0) | 2023.02.25 |
프로젝트(4) - DB에 저장할 속성 (0) | 2023.02.08 |
프로젝트(2) - MongoDB 연결 (0) | 2023.02.08 |