[MongoDB] Create Subdocument multiple times / subdoc 복수개 생성하기.

Q kim·2020년 12월 5일
0

MongoDB

목록 보기
1/7

복수개의 Subdoc 생성하기.

몽고DB는 RDB처럼 데이터끼리 관계로 연결시키기보다는,
연관된 데이터, 같이 이용될 확률이 높은 데이터를 한뭉텅이로 저장하는게 일반적이다
그 방식을 Embedding시킨다고 한다. 아래는 embed 방식의 모델을 보여준다.

// video객체를 복수개 가지는 user 모델.
const Video = {
	URI: String
}

const UserSchema = new mongoose.Schema({
  name: String,
  videos: [Video]
});


export const UserModelForSubdoc = mongoose.model('User', UserSchema);

위 모델에 한번의 query를 해서 아래의 값을 얻고 싶은데 어떻게 해야하는가.
for문으로 query를 복수개 날릴순 없지않나... for은 최후의 방식이다.

// 무식하게 for문으로 query를 두번날린다면 이렇게 된다.
for (let i of inputList) {
    await Model.findByIdAndUpdate(
	userID, 
	{ $push: { videos: { URI : i } } }, 
	{new: true});
}

위 for문 방식을 하지 않고 아래의 원하는 결과값을 받으려면 어떻게 해야하는지 알아보자.

//원하는 결과값
{
  "result": {
    "_id": "dsfheiofjkdlsfmklsdfm",
    "name": "브레드",
    "videos": [
      {
        "_id": "5fca3a6e3a0a6f4360495ba7",
        "URI": "https1"
      },
      {
        "_id": "5fca3a6e3a0a6f4360495ba8",
        "URI": "https2"
      }
    ],
  }
}

Embding된 모델에서 video(subdoc)를 복수개 생성하고 싶을 때는 어떻게 해야할까?
단순히 $push?하면 되지않나? "아니다". 먼저 알야아할 게 있다. 바로 $each 연산자!

몽고DB의 설명부터 보자.

$each

The $each modifier is available for use with the $addToSet operator and the $push operator.
Use with the $addToSet operator to add multiple values to an array <field> if the values do not exist in the <field>.

"Array field에 복수개의 값을 넣어줄때 $push 와 $addToSet과 같이 이용하면 된다."

써보자. - 일단 $each 기초부터.

복수개의 subdoc을 생성하기전에 한단계 쉬운 Array Field에 복수개의 데이터를 넣어보자.

const UserSchema = new mongoose.Schema({
  name: String,
  videos: [String]
});

export const UserModel1 = mongoose.model('User', UserSchema);

userModel1의 videos field에 복수개의 데이터를 추가하는 방법은 아주 간단하다.

MongoDB document

Use with the $push operator to append multiple values to an array field
{ $push: { field: { $each: [ value1, value2 ... ] } } }

추가하려는 값의 array에 $each를 붙여주면 된다.
한개의 값을 추가할 때 이랬다면. { field: value1 }
복수개의 값을 추가할때는 이렇게 바뀐다. { field: { $each: [value1, value2] } }

$each를 Sobdoc를 생성하는 상황에서도 활용해보자 !

다시 우리의 문제 상황으로 돌아오자.
우리가 하고자 하는 건: "아래의 모델에 복수개의 Subdoc을 한번의 query로 생성한다."

// video객체를 복수개 가지는 user 모델.
const Video = {
	URI: String
}

const UserSchema = new mongoose.Schema({
  name: String,
  videos: [Video]
});


export const UserModelForSubdoc = mongoose.model('User', UserSchema);
//원하는 결과값
{
  "result": {
    "_id": "dsfheiofjkdlsfmklsdfm",
    "name": "브레드",
    "videos": [
      {
        "_id": "5fca3a6e3a0a6f4360495ba7",
        "URI": "https1"
      },
      {
        "_id": "5fca3a6e3a0a6f4360495ba8",
        "URI": "https2"
      }
    ],
  }
}

해결 방법

// URIInputs = [ "http1", "http2", "http3" ];
let array = [];
for (let i = 0; i < URIInputs.length; i++) {
  var obj = {};
  obj['URI'] = URIInputs[i];
  array.push(obj);
}
// array = [ {"URI" : "http1"}, {"URI": "http2"}, {"URI": "http3"} ]

let checkSubdoc = await this.userModel
  .findOneAndUpdate(
    { _id: user._id }, 
    { $push: { videos: { $each: array } } }, 
    { new: true }
);

Subdoc는 단순 field가 아니기때문에 값만 떡하니 보낸다고 생성되지 않는다.
object로 값을 보내줘야한다. 그래서 key, value가 있는 object로 바꿔줬고 object들을 한 array에 모두 push했다.
그 뒤 단순 field를 push 업데이트하듯이 $each 연산자와 $push연산자를 같이 이용해서 subdoc를 복수개 생성하게 했다.

profile
https://medium.com/nodejs-server

0개의 댓글