정환타 개발노트

MongoDB Model(모델) 활용 본문

Dev-Database/NoSQL

MongoDB Model(모델) 활용

JungHwanTa 2020. 2. 5. 14:25

MongoDB를 사용한다면, 여러가지 Application 환경에서 다양한 모델을 적용하여 활용할 수 있다.

연관 동작 수행

MongoDB에서 단일 document에 대한 쓰기 동작을 유기적으로 수행 할 수 있다.

만약 여러개의 필드가 서로 영향을 미친다면, 같은 document가 그 필드를 포함하면 효율적으로 동작을 수행할 수 있다.

 

예를들어, 책과 대여가능한 권수, 대여 정보를 유지하는 상황에서, 대여가능 권수(available)와 대여 정보(checkout)는 서로 연관되어 처리해야 한다.

{
    _id: 123456789,
    title: "MongoDB: The Definitive Guide",
    author: [ "Kristina Chodorow", "Mike Dirolf" ],
    published_date: ISODate("2010-09-24"),
    pages: 216,
    language: "English",
    publisher_id: "oreilly",
    available: 3,
    checkout: [ { by: "joe", date: ISODate("2012-10-15") } ]
}

만약 데이터를 업데이트 하는 상황에서는 다음과 같이 처리할 수 있다.

db.books.updateOne (
   { _id: 123456789, available: { $gt: 0 } },
   {
     $inc: { available: -1 },
     $push: { checkout: { by: "name", date: new Date() } }
   }
)

키워드 검색

응용 프로그램에서 텍스트를 저장하는 필드에 대해서 쿼리를 수행하는 경우, 일치하는 텍스트를 찾아 조회해야 한다.

이러한 상황에서 MongoDB에서 키워드 검색을 위한 방법은 아래의 한가지이다.

documenet에 배열 필드를 만들고 키워드를 배열에 문자열로 추가를 한다.

배열에 키 인덱스를 생성하여 값을 조회한다.

키 인덱스를 생성하는 방식은 다음과 같다.

db.volumes.createIndex( { <field>: "text" } )
db.volumes.createIndex( { topics: "text" } )

키 인덱스를 생성하면 find를 이용하여 문자열 조회를 할 수 있다.

db.volumes.findOne( { topics : "voyage" }, { title: 1 } )

화폐 데이터

응용프로그램에서 화폐 데이터를 처리할 때, 만약 산술을 처리한다면 정확한 정밀도로 10진수 반올림 처리를 할 수 있는 기능이 필요하다.

현대에 많이 사용하는 이진 기반 소수점 산술들은 정확한 소수를 표현할 수 없다. 따라서 통화 산술에는 적합하지 않다.

 

MongoDB에서는 화폐 데이터를 산술 할 수 있는 몇가지 기능을 제공한다. 

 

일단 화폐 데이터가 숫자 데이터 혹은 숫자가 아닌 데이터로 나뉠 수 있다.

 

숫자 데이터

10진수 BSON Type 사용

10진수 BSON Type을 사용하면 이진 기반 부동소수점 형식과 달리 통화 데이터 처리를 정확하게 할 수 있다.

 

10진수 값은 NumberDecimal()을 통해 활용이 가능하다.

아래는 가스 가격이 포함된 document 데이터를 gasprices 컬렉션에 포함하는 식이다.

db.gasprices.insert{ "_id" : 1, "date" : ISODate(), "price" : NumberDecimal("2.099"), "station" : "Quikstop", "grade" : "regular" }

10진수 데이터를 조회하는 식은 다음과 같다.

db.gasprices.find( { price: NumberDecimal("2.099") } )

 

숫자가 아닌 데이터

숫자가 아닌 데이터를 통화 데이터로 사용하기 위해서는 두 필드에 값을 저장해야 한다.

 

1. 첫번째 필드는 숫자가 아닌 데이터 유형(BinData or String)으로 입력(화폐 데이터)

2. 두번째 필드에는 정확한 값을 부동 소수점으로 입력(최대 근사치값)

{
  price: { display: "9.99", approx: 9.9900000000000002, currency: "USD" },
  fee: { display: "0.25", approx: 0.2499999999999999, currency: "USD" }
}

 

Comments