MongoDB에서 배열 형태로 저장된 내장(embedded) 문서를 조건에 따라 조회하고, 해당 조건이 충족될 때 새로운 문서를 배열에 추가하려면 update 연산과 함께 $push 연산자를 사용하면 됩니다.
특히 $nin 연산자를 조건으로 활용하면, 특정 값이 아직 배열에 존재하지 않는 경우에만 새 문서를 추가하는 로직을 손쉽게 구현할 수 있습니다. 아래 예제를 통해 단계별로 살펴보겠습니다.
1. 컬렉션 생성 및 문서 삽입
먼저 데모용 컬렉션을 만들고 내장 문서 배열을 포함한 데이터를 삽입합니다.
> db.demo573.insertOne(
... {
... '_id' :101,
... 'SearchInformation' : [
... {
... 'Site' : 'Facebook.com',
... 'NumberOfHits' : 100
... },
... {
... 'Site' : 'Twitter.com',
... 'NumberOfHits' : 300
... }
... ]
... }
... );
{ "acknowledged" : true, "insertedId" : 101 }2. 삽입된 문서 확인하기
find() 메서드를 사용해 컬렉션의 모든 문서를 조회합니다.
> db.demo573.find();
실행 결과는 다음과 같습니다.
{ "_id" : 101, "SearchInformation" : [ { "Site" : "Facebook.com", "NumberOfHits" : 100 }, { "Site" : "Twitter.com", "NumberOfHits" : 300 } ] }3. $push와 $nin을 활용한 조건부 업데이트
이제 핵심 단계입니다. $nin 연산자로 'Google.com'이라는 사이트가 SearchInformation 배열에 없는 경우에만 매칭되도록 조건을 설정하고, 해당 조건이 충족되면 $push로 새로운 내장 문서를 배열 끝에 추가합니다.
> db.demo573.update({
... _id: 101,
... "SearchInformation.Site": {
... $nin: ["Google.com"]
... }
... }, {
... $push: {
... "SearchInformation": {
... 'Site' : 'Google.com',
... 'NumberOfHits' : 10000
... }
... }
... });
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })WriteResult의 nMatched: 1과 nModified: 1은 조건에 맞는 문서가 하나 찾아졌고, 실제로 수정이 성공적으로 이루어졌음을 의미합니다.
4. 업데이트 결과 확인
find() 메서드에 pretty()를 붙여 가독성 좋게 결과를 출력해 봅니다.
> db.demo573.find().pretty();
실행 결과는 다음과 같습니다.
{
"_id" : 101,
"SearchInformation" : [
{
"Site" : "Facebook.com",
"NumberOfHits" : 100
},
{
"Site" : "Twitter.com",
"NumberOfHits" : 300
},
{
"Site" : "Google.com",
"NumberOfHits" : 10000
}
]
}정리
이처럼 MongoDB에서는 update 쿼리의 조건 절에 $nin을 사용해 중복 여부를 검사하고, 업데이트 절에서 $push를 사용해 새로운 내장 문서를 배열에 안전하게 추가할 수 있습니다. 이 패턴은 사이트 방문 정보, 태그 목록, 사용자 활동 기록 등 중복 입력을 방지하면서 배열 데이터를 관리해야 하는 상황에서 매우 유용하게 활용됩니다.