The Web Developer - (Udemy)_ Mongo와 데이터 연결하기

‍정진철·2022년 8월 10일
0

web devloper (udemy)

목록 보기
19/34

1) One to Few 관계

Embed the data directly in the document !

  • 사용자가 두가지나 그 이상의 여러가지 항목을 가질 때 사용.
<user.js>


const mongoose = require('mongoose');


mongoose.connect('mongodb://localhost:27017/relationshipDemo', {
    useNewUrlParser: true,
    useUnifiedTopology: true
});

//스키마
const userSchema = new mongoose.Schema({
    first: String,
    last: String,
    addresses: [
        {   
            _id: {id: false},
            street : String,
            city: String,
            state: String,
            county: String


        }
    ]
})

//모델 생성(User)
const User = mongoose.model('User', userSchema);



const db = mongoose.connection;
db.on("error", console.error.bind(console, "connection error:"));
db.once("open", () => {
    console.log("Database connected");
});


const makeUser = async() => {
    const u = new User({
        first: 'Harry',
        last : 'Porter'

    })
    u.addresses.push({
        street : '123 Sesame St.',
        city: 'New york',
        state: 'New york',
        county: 'USA'
    })
    const res = await u.save();
    console.log(res);
} 

//새 주소 추가하기.
const addAddress = async(id) => {
    const user = await User.findById(id);
    user.addresses.push(
        {
        street : '99 3rd St.',
        city: 'New york',
        state: 'New york',
        county: 'USA'
        }
    )
    //주소가 업데이트된 user 저장
    const res = await user.save();
    console.log(res);
}


addAddress('62f2400002f7d044d334c4e8');


2) One to Many 관계

one option is to store your data separately, but then store references to document ID's somewhere inside the parent (한 농장 판매 간판대의 다양한 메론 종류들)

<farm.js>

const Schema = mongoose.Schema;

const productSchema = new Schema({
   name: String,
   price: Number,
   season: {
       type: String,
       enum: ['Spring', 'Summer', 'Fall', 'Winter']
   }
})


const farmSchema = new Schema({
   name: String,
   city: String,
   //prodcucts의 문서인 엔티티 각각의 타입이 객체 ID 라고 알려줌.
   //상품ID의 배열들이므로 ref는 모델의 이름인 'Product'를 사용하면됨.
   products: [{type: Schema.Types.ObjectId, ref: 'Product'}]

})

const Product = mongoose.model('Product', productSchema);
const Farm = mongoose.model('Farm', farmSchema)


const makeFarm = async () => {
   const farm = new Farm({ name: 'Full Belly Farms', city: 'Guinda, CA'}) 
   const melon =  Farm.findOne({name: 'Goddess Melon'})
   farm.products.push(melon);
};


makeFarm();

node farm.js


3) Mongoose의 Populate 명령어

Populate

const mongoose = require('mongoose');
const { Schema } = mongoose;

mongoose.connect('mongodb://localhost:27017/relationshipDemo', { useNewUrlParser: true, useUnifiedTopology: true })
    .then(() => {
        console.log("MONGO CONNECTION OPEN!!!")
    })
    .catch(err => {
        console.log("OH NO MONGO CONNECTION ERROR!!!!")
        console.log(err)
    })

const productSchema = new Schema({
    name: String,
    price: Number,
    season: {
        type: String,
        enum: ['Spring', 'Summer', 'Fall', 'Winter']
    }
})


const farmSchema = new Schema({
    name: String,
    city: String,
    //prodcucts의 문서인 엔티티 각각의 타입이 객체 ID 라고 알려줌.
    //상품ID의 배열들이므로 ref는 모델의 이름인 'Product'를 사용하면됨.
    products: [{ type : Schema.Types.ObjectId, ref: 'Product' }]

})

const Product = mongoose.model('Product', productSchema);
const Farm = mongoose.model('Farm', farmSchema)


//Product.insertMany([
   // {name: 'Goddess Melon', price: 4.99, season: 'Summer'},
    //{name: 'Sugar Baby WaterMelon', price: 4.99, season: 'Summer'},
   // {name: 'Asparagus', price: 3.99, season: 'Spring'},
//])




const makeFarm = async () => {
    const farm = new Farm({ name: 'Full Belly Farms', city: 'Guinda, CA' });
    const melon = await Product.findOne({ name: 'Goddess Melon' });
    farm.products.push(melon)
    await farm.save()
    console.log(farm);
}

const addProduct = async () => {
    const farm = await Farm.findOne({ name: 'Full Belly Farms' });
    const watermelon = await Product.findOne({ name: 'Sugar Baby Watermelon' });
    farm.products.push(watermelon);
    await farm.save();
    console.log(farm);
}


Farm.findOne({ name : 'Belly Farms'})
.populate('products')
.then(farm => console.log(farm))

4) One to “Bajillions” 관계

한명의 사람이 여러개의 트윗을 남겼을 때 ( 동일한 객체 아이디 유지)

with thousands or more documents, it's more efficient to store a reference to the parent on the child document.

<tweet.js>


    const userSchema = new Schema({
        username: String,
        age: Number,

    })

    const tweetSchema = new Schema({
        text: String,
        likes: Number,
        user: {type: Schema.Types.ObjectId , ref: 'User'} 
    })


const User = mongoose.model('User', userSchema);
const Tweet = mongoose.model('Tweet', tweetSchema)

const makeTweets= async() => {
    const user = new User({username: 'jincheol', age: 24})
    const tweet1 = new Tweet({text:'i love coding', likes:999})
    tweet1.user = user;
    user.save()
    tweet1.save();


}
  • user를 나타내는 전체 객체를 가져다 tweet1의 user로 설정함
    (ObjectID로 뜨는걸 확인할 수 있음)

2번째 트윗


user 정보 populate 하기

  • user가 객체ID로 출력되는걸 확인할 수 있음.


  • populate 적용 후

특정 정보만 추출 (username)


모든 트윗에 대한 유저정보 추출


5) Mongo 스키마 디자인

Rules of Thumb

  • 1) 그러지 말아야 할 이유가 딱히 없는 한 우선은 정보를 임베드 하라.
  • 2) 객체에 따로 엑세스 하는 경우가 임베드 하지 않을 이유이다.
  • 3) 제한이 없이 계속해서 커지기만 하는 배열은 항상 피해야 한다.
  • 4) 비정규화시 읽기-쓰기 비율을 고려하라.
  • 5) 항상 Mongo를 쓸 땐 데이터를 모델링하는 방식은 전적으로 데이터 엑세스 패턴에 달려있다.
    (중요) - 데이터를 구조화할 때는 앱이 쿼리하고 업데이트 하는 방식에 맞춰라.
profile
WILL is ALL

0개의 댓글