on
MongoDB 클라우드 생성하고 요소수 데이터 삽입하기
MongoDB 클라우드 생성하고 요소수 데이터 삽입하기
이 글은 요소수WHERE이라는 사이트의 개발일지입니다.
http://yososuwhere.site/
이전 포스팅에는 공공 데이터 포털에서 요소수를 판매하는 주유소에 대한 데이터를 얻는 것 까지 다뤘다. 이번 포스팅에는 해당 데이터를 저장하기 위해 MongoDB 클라우드를 생성하고, 데이터를 업로드하는 과정까지 다룬다.
왜 MongoDB인가?
데이터베이스를 직접 구축하는 것은 꽤나 짜증나는 일이다. 근데 mongodb atlas라는 곳에서 MongoDB를 제한적으로 무료로 제공한다. 그것만으로도 MongoDB를 사용하는 이유를 댈수 있을 것 같다. 물론 MongoDB 자체가 사용하기 쉬운 DB이기도 하다.
MongoDB 클라우드 생성하기
구글에 mongodb 검색하여 첫번째 사이트 들어가기
회원가입 진행 및 DB 생성하기
간단하게 구글 아이디로 회원가입을 할 수 있고, 회원가입을 하는 도중에 DB를 생성하게 된다. 무료 클라우드를 사용하기 위해서 Shared 옵션을 선택하도록 한다.
그리고 aws를 선택하고, DB가 물리적으로 존재하는 국가를 선택하게 되는데, 그냥 가까운 일본을 선택했다.
Cluster Tier는 무료인 M0 Sandbox를 선택한다.
Cluster Name에는 자신이 사용하고 싶은 이름을 적는다.
그리고 Create Cluster를 클릭해 최종적으로 생성한다.
Security와 관련해서는 Username and Password를 선택하고, 자신이 사용할 아이디와 패스워드를 적는다. 이것으로 DB에 접근하게 된다.
IP Access List에 모든 접근을 허용한다는 뜻으로 0.0.0.0/0 을 입력한다. Finish and Close를 누르면 모든 세팅이 끝난다.
그리고 아래와 같은 화면을 보게 된다면 성공이다!
NodeJS에서 DB 연결하기
Connect를 누르면 아래와 같은 화면이 나온다. 우리는 우리의 Application인 Node JS로 연결할 것이므로 "Connect your application"을 누른다.
그러면 아래와 같은 화면이 나오고 DB에 접속할 수 있는 주소가 나온다. 에 자기 DB의 패스워드를 입력하면 된다.
공공 데이터 API 호출부터 DB 삽입까지
요소수 공공 데이터 API를 호출하면 데이터 형식이 JSON인 string 값이다. 그렇기에 굳이 JSON으로 펼쳐서 DB에 넣을 필요가 없고 그냥 string 그 자체로 저장하면 된다. 자세한 것은 코드와 함께 설명하도록 하겠다. 맨 아래에 full code가 있다.
Mongoose 선언
const mongoose = require("mongoose") let db = mongoose.connection; db.on("error", () => { console.log("mongodb error") }) db.once("open", () => { console.log("connected") })
Schema 정의하기
//Define Schema var GasstationSchema = mongoose.Schema({ id: String, data_string: String });
데이터의 스키마를 정의한다. string 하나를 저장하는 것이 목적이고, 요소수 데이터 API의 호출 결과가 전부 이 string에 입력된다. id는 검색, 업데이트를 위한 속성값이다. 무조건 0의 값을 가지도록 했다.
DB 연결
//Compile schema to model var Gasstation = db.model('Gasstation', GasstationSchema); const userConfig = require("../config/userConfig.json") mongoose.connect( `mongodb+srv://${userConfig.id}:${userConfig.password}@yososuwhere.xxxxx.mongodb.net/yososuwhere?retryWrites=true&w;=majority` , {useNewUrlParser:true, useUnifiedTopology:true} )
//userConfig.json { "id" : "자신의 MongoDB ID", "password" : "자신의 MongoDB PW", "api2ServiceKey" : "요소수 공공 API service key", }
실제로 DB에 접속하는 부분이다. ` ` 문자에 주의해야한다. 따옴표가 아니고 백틱(backtick)이라는 문자다. 그리고 mongoose.connect할때 접속하는 주소는 MongoDB Atlas에서 알수있는 자신의 주소를 사용해야한다. 그리고 보안상 아이디와 비밀번호는 userConfig.json이라는 다른 파일에 정의해두었다.
공공 API request 세팅
//공공 API request 관련 세팅 var request = require('request'); const { $where } = require('../model/location'); var url = 'https://api.odcloud.kr/api/uws/v1/inventory' var queryParams = '?' + encodeURIComponent('serviceKey') + `=${userConfig.api2ServiceKey}`; /* Service Key*/ queryParams += '&' + encodeURIComponent('page') + '=' + encodeURIComponent('1'); /* */ queryParams += '&' + encodeURIComponent('perPage') + '=' + encodeURIComponent('2000'); /* */
이부분은 지난번에 작성한 글을 참고하면 된다. GET request를 위한 주소를 세팅한다.
요소수 데이터 요청 이후 DB 삽입하기
function requestGasstationData(){ //공공 API 요청 날리기 request({ url: url + queryParams, method: 'GET' }, async function (error, response, body) { //공공 API 응답 왔을 때 const filter = {id: "0"}; const update = { id: "0", data_string: body }; //DB에서 id: 0 인 것을 찾고, 있으면 업데이트, 없으면 삽입 Gasstation.findOneAndUpdate( filter, update, { "new":true, "upsert":true, }, function(err, res){ // console.log(err) // console.log(res) } ); }); }
위에서 만든 데이터 요청 주소에 GET request를 날리면 아래 부분인 async function {...} 이 호출된다. 데이터는 body에 담겨있다. 이 데이터를 DB에 넣는 코드다.
주기적으로 실행하기
//60초 마다 실행 시키기 setInterval(function(){ requestGasstationData(); }, 60000); // interval example
DB를 꾸준히 쌓기 위해 60초마다 실행한다.
전체 코드
const mongoose = require("mongoose") let db = mongoose.connection; db.on("error", () => { console.log("mongodb error") }) db.once("open", () => { console.log("connected") }) //Define Schema var GasstationSchema = mongoose.Schema({ id: String, data_string: String }); //Compile schema to model var Gasstation = db.model('Gasstation', GasstationSchema); const userConfig = require("../config/userConfig.json") mongoose.connect( `mongodb+srv://${userConfig.id}:${userConfig.password}@yososuwhere.xxxxx.mongodb.net/yososuwhere?retryWrites=true&w;=majority` , {useNewUrlParser:true, useUnifiedTopology:true} ) //공공 API request 관련 세팅 var request = require('request'); const { $where } = require('../model/location'); var url = 'https://api.odcloud.kr/api/uws/v1/inventory' var queryParams = '?' + encodeURIComponent('serviceKey') + `=${userConfig.api2ServiceKey}`; /* Service Key*/ queryParams += '&' + encodeURIComponent('page') + '=' + encodeURIComponent('1'); /* */ queryParams += '&' + encodeURIComponent('perPage') + '=' + encodeURIComponent('2000'); /* */ function requestGasstationData(){ //공공 API 요청 날리기 request({ url: url + queryParams, method: 'GET' }, async function (error, response, body) { //공공 API 응답 왔을 때 const filter = {id: "0"}; const update = { id: "0", data_string: body }; //DB에서 id: 0 인 것을 찾고, 있으면 업데이트, 없으면 삽입 Gasstation.findOneAndUpdate( filter, update, { "new":true, "upsert":true, }, function(err, res){ // console.log(err) // console.log(res) } ); }); } requestGasstationData(); //60초 마다 실행 시키기 setInterval(function(){ requestGasstationData(); }, 60000); // interval example
실행하기
실행은 node js로 한다. 코드 상에서 userConfig.json의 위치를 맞추기 위해 디렉토리 구조를 변경해야할수도 있고 아니면 코드를 고쳐도 된다.
node 파일명.js
Atlas에서 Browse Collections 버튼을 누르면 DB의 내용을 볼 수 있다. 그러면 아래 처럼 데이터가 저장되는 것을 확인할수 있다.
결론
이번 포스팅은 배경 지식이 없다면 어려울 수 있다. 블로그 글을 쓸때마다 딜레마인게, 누가 읽어도 차근차근 쉽게 따라할 수 있게 글을 쓰고는 싶으나 그렇게 쓰려면 사실 시간이 몇배로 든다. 그래서 적당히 타협해서 내가 나중에 봤을때 다시 기억을 해낼수 있을 정도로만 수준을 맞추고 있다. 아무튼 그렇다...
精進.
from http://yoondevel.tistory.com/5 by ccl(A) rewrite - 2021-12-21 20:26:32