사붐이개발일기

공공데이터(json)으로 인덱싱하기 본문

Database/MongoDB

공공데이터(json)으로 인덱싱하기

sabeom 2023. 2. 7. 17:56

목표: 국민민건강보험공단_건강검진정보 데이터(json)를 인덱싱하여 before, after 속도체크


데이터_URL: https://www.data.go.kr/data/15007122/fileData.do

 

공공데이터 포털

국가에서 보유하고 있는 다양한 데이터를『공공데이터의 제공 및 이용 활성화에 관한 법률(제11956호)』에 따라 개방하여 국민들이 보다 쉽고 용이하게 공유•활용할 수 있도록 공공데이터(Datase

www.data.go.kr


python에서 json데이터를 mongoDB로 저장하기:

import requests
import json
import pymongo

conn = pymongo.MongoClient()
db = conn.bitDB

min_page = 1
max_page = 5000
key = '인증키_입력'

url = 'https://api.odcloud.kr/api/15007122/v1/uddi:95d6cbf2-f800-4ce3-a4f7-f57823274732?serviceKey=%s&pageNo=%d&perPage=%d&type=json' % (key, min_page, max_page)
print(url)
response = requests.get(url)
contents = response.text

json_ob = json.loads(contents)

health_info = list()

for json in json_ob['data']:
    del json['(혈청지오티)ALT']
    del json['(혈청지오티)AST']
    del json['HDL 콜레스테롤']
    del json['LDL 콜레스테롤']
    del json['감마 지티피']
    del json['구강검진 수검여부']
    del json['요단백']
    del json['치아우식증유무']
    del json['트리글리세라이드']
    del json['혈색소']
    del json['혈청크레아티닌']

index = 0

# 가입자 일련번호, 기준년도, 성별코드, 수축기 혈압, 시력(우), 시력(좌), 식전혈당(공복혈당), 신장(5Cm단위),
# 연령대 코드(5세단위), 이완기 혈압, 청력(우), 청력(좌), 체중(5Kg 단위), 치석, 허리둘레, 흡연상태
for _ in range(8):
    for json in json_ob['data']:
        dict1 = dict()
        index += 1
        dict1['가입자 일련번호'] = str(index)
        dict1["기준년도"] = str(json['기준년도'])
        dict1["성별코드"]= str(json['성별코드'])
        dict1["수축기 혈압"]= str(json['수축기 혈압'])
        dict1["시력(우)"]= str(json['시력(우)'])
        dict1["시력(좌)"]= str(json['시력(좌)'])
        dict1["식전혈당(공복혈당)"]= str(json['식전혈당(공복혈당)'])
        dict1["신장(5Cm단위)"]= str(json['신장(5Cm단위)'])
        dict1["연령대 코드(5세단위)"]= str(json['연령대 코드(5세단위)'])
        dict1["이완기 혈압"]= str(json['이완기 혈압'])
        dict1["청력(우)"]= str(json['청력(우)'])
        dict1["청력(좌)"]= str(json['청력(좌)'])
        dict1["체중(5Kg 단위)"]= str(json['체중(5Kg 단위)'])
        dict1["치석"]= str(json['치석'])
        dict1["허리둘레"]= str(json['허리둘레'])
        dict1["흡연상태"]= str(json['흡연상태'])

        health_info.append(dict1)

for health in health_info:
    print(health)

db.healths.insert_many(health_info)

mongoDB_관련 객체 및 생성목록:

  • 데이터베이스 이름: bitDB
  • 컬렉션 이름: healths
  • 인덱스 생성 명령어:
    • db.healths.createIndex({"가입자 일련번호":1})
    • db.healths.createIndex({"신장(5Cm단위)" : "text"})
  • index("가입자 일련번호") before
    • db.healths.find({"가입자 일련번호" : "12211"})

  • index("가입자 일련번호") after
    • db.healths.find({"가입자 일련번호" : "12211"})

  • text_index("신장(5Cm단위)") before
    • db.healths.find({"신장(5Cm단위)" : {"$regex": "17.*"}})

  • text_index("신장(5Cm단위)") after
    • db.healths.find({"$text": {"$search": "17.*"}})


 위의 이미지를 보면 index("가입자 일련번호")  는 '24' (before) 에서 '10' (after) 으로, text_index("신장(5Cm단위)") 는 '91' 에서 '0' 으로 줄어들것을 볼 수 있다.

 

 인덱스는 검색 속도를 높이기 위한 데이터 구조이다. 반면에 쓰기 작업을 할 때 인덱스를 재구성하기 위한 비용이 발생하고 별도의 저장공간도 발생하게 된다. 성능을 높이기 위한 trade-off로 생각하면된다. 인덱스는 일반적으로 키-필드 구조로 이루어져있고 테이블에 대한 세부 정보를 가지지 않는다. 별도의 세부 정보의 이용없이 키 값을 기초로 하기 때문에 검색과 정렬속도를 향상시킨다. 그래서 일반적으로 대부분의 DBMS는 primary key를 자동으로 인덱싱한다.

 

 하지만 비교연산 부분에선 인덱스를 쓰면 더 늘어나기도 하니 어떤 데이터에 인덱스를 붙일지 주의해서 사용하자.

 

 

인덱싱을 사용하면 좋은 케이스

- 데이터의 양이 많고, 검색이 변경보다 잦은 경우

- 인덱스를 사용하고자 하는 컬럼의 값이 다양한 경우

'Database > MongoDB' 카테고리의 다른 글

mongoDB 4일차 (공간정보 GeoJSON)  (1) 2023.02.08
mongoDB 3일차 (cursor, indexing)  (0) 2023.02.07
SQL vs mongoDB (용어 및 예제)  (0) 2023.02.07
mongoDB 2일차 (CRUD)  (0) 2023.02.07
mongoDB 와 Python 연동 (동적 웹크롤링)  (0) 2023.02.06