페어 활동 기록_Day11_윤우_현정 - boostcampwm-2022/web33-Mildo GitHub Wiki
✂️ 분배된 이슈
- 서울 도시 데이터 비동기 처리로 속도 향상
- MongoDB 연결
- 데이터를 가공해서 DB에 저장하기(CRUD)
🚩 구현 목표
- 서울 실시간 도시 데이터 속도를 향상한다.
- 데이터베이스와 연결하여 저장한다.
- 주요 50곳의 장소의 위도/경도를 처리한다.
🍀 세부 목표
- 서울 도시 데이터 50개를 불러올 때 Promise를 이용해서 비동기 처리
- controller, service 분리
- mongoose를 이용해서 MongoDB와 연결
- 스키마 생성
- 장소
- 밀도
- 데이터 저장
🖥️ 구현 내용
장소 10곳 동기처리
- 1차 시도 : 26.73초
- 2차 시도 : 25.57초
장소 10곳 비동기처리
- 50곳 시도 : 15.02초
- 10곳 1차 시도 : 6.04초
- 10곳 2차 시도 : 5.70초
- 속도가 향상되지만 몇몇 장소의 데이터를 못 불러오는 현상이 발생한다.
⇒ 다시 동기 처리로 변경
📖 학습 내용
Mongoose insertMany
- 배열에 있는 데이터를
map
으로 돌리면서 하나하나 insert해주면 시간이 오래 걸림 insertMany
: 배열에 있는 데이터를 통째로 insert해주는 메소드
DataSchema.insertMany(dataArray)
.then(() => {
console.log('data inserted');
})
.catch(e => {
console.log(e);
});
🩺 의사결정
MongoDB 스키마 설계
- 다 때려박기
- 문제점
- 장소명, 위도, 경도가 중복되어서 들어감
- 장점
- 구현이 쉬움
- NoSQL의 장점을 살릴 수 있음
- 문제점
- Embeded
- 문제점
- 하나의 필드값이 무한으로 커짐
- 이럴 때는 차라리 Reference를 사용하는 것이 낫다고 함
- 장점
- 테이블 상태를 한 번에 볼 수 있음
- 문제점
- Reference
- 문제점
- 장소명, 위도, 경도 이외에는 중복되는 값이 없어 이것 때문에 참조를 해야 될까란 의문
- 관계가 많아지면 sql보다 느려질 수 있음
- 성능 등 MongoDB의 장점을 살릴 수 없음
- 장점
- 중복되는 값(장소명, 위도/경도)을 계속 추가하지 않아도 됨
- 문제점
- 참고 사이트
주요 장소 데이터 위치
- 서버에서 상수로 갖고 사용하기 → 다 때려박기로 사용하기 좋아보임
- 데이터베이스에 저장 X
- 데이터베이스에 저장
- 데이터베이스에 넣어서 사용하기
-
reference로 사용하기 좋아보임
-
reference로 사용하지 않아도 됨
- 장소 다큐먼트(장소명, 좌표) → 고정
- 핀 그릴 때
- 주요 장소가 늘어날 때 유지보수가 좋음
- 밀도 다큐먼트(장소명, 밀도, 인구수, 시간) → api로 계속 찔러옴
- 밀도, 인구수
⇒ 굳이 join하지 않아도 된다.
- 장소 다큐먼트(장소명, 좌표) → 고정
-
🚧 Trouble Shooting
Promise 오류
-
기존 코드
const cityData: cityDataTypes[] = await Promise.all( Object.keys(AREA_NAMES).map(async areaName => { const data = await getAxiosSeoulArea(areaName); // Promise.all const json = await xml2js.parseStringPromise(data); // Promise.all if (json['Map']) { console.log(`실패: ${areaName}`); return { areaName: null, populationMin: null, populationMax: null, populationLevel: null, updatedAt: null }; } ... return { areaName: AREA_NM[0], populationMin: AREA_PPLTN_MIN[0], populationMax: AREA_PPLTN_MAX[0], populationLevel: AREA_CONGEST_LVL[0], updatedAt: PPLTN_TIME[0] }; }) );
- 서울 실시간 도시 데이터 API에서 데이터를 받아오는 로직, json으로 변환하는 로직, 데이터를 가공하는 로직이 하나의 Promise.all 에 넣어져 있었음
-
수정 후 코드
const cityDataXml = await Promise.all( Object.keys(AREA_NAMES).map(async areaName => getAxiosSeoulArea(areaName) ) ); const cityDataJson = await Promise.all( cityDataXml.map(async xml => xml2js.parseStringPromise(xml)) ); const cityData = cityDataJson.map(json => { if (json['Map']) { console.log(`실패`); return { areaName: null, populationMin: null, populationMax: null, populationLevel: null, updatedAt: null }; } ... return { areaName: AREA_NM[0], populationMin: AREA_PPLTN_MIN[0], populationMax: AREA_PPLTN_MAX[0], populationLevel: AREA_CONGEST_LVL[0], updatedAt: PPLTN_TIME[0] }; });
-
서울 실시간 도시 데이터 API에서 데이터를 받아오는 로직과 json으로 변환하는 로직을 각각의 Promise.all로 처리한 후 데이터 가공은 따로
map
을 사용하여 처리 -
10장소씩은 성공하는 듯 보였지만 이전과 차이 없이 데이터를 가져오지 못하고 있다. 서울시 공공데이터 API에서 오류가 발생하여 다시 동기 처리로 바꾸어야 했다.
-
❓ 궁금한 점
🎸 기타
인덱싱으로 mongoDB 성능 향상시키기
- Population 스키마에서 장소명을 인덱싱하면 이후 탐색할때 속도 향상을 체감할 수 있을 것 같다.