imhamburger 님의 블로그
데이터엔지니어 부트캠프 - MongoDB에 적재할 때 중복값 처리하기 본문
파이널 프로젝트에서 DB 설계를 하던 중 3개의 웹사이트에서 크롤링한 데이터를 DB에 적재할 때 중복값 처리는 어떻게 할지 고민이었다.
같은 웹사이트에서 가져오는 데이터라면 고유번호를 기준으로 DB에 적재하면 되는데 각기 다른 사이트이기에 이 방법은 쓸 수 없었다.
하지만 중복값이라는 건 어쨋든 같은 데이터이기 때문에...
대표 1개의 웹사이트를 정해서 먼저 DB에 데이터를 적재한 후,
나머지 2개를 DB에 넣을 때 같은 값이 있을 경우에 "hosts"라는 컬럼 안에 site_id와 url 이 추가되는 것으로 처리하였다.
Mongodb 초기 설계
{
"_id": ObjectId("..."),
"title": "뮤지컬 공연 제목",
"start_time": "2024-11-20T19:00:00",
"end_time": "2024-11-20T21:00:00",
"price": "50000",
"location": "서울",
"hosts": [
{
"host_name": "A 사이트",
"url": "https://a-site.com/show/123",
"site_id": 1
},
{
"host_name": "B 사이트",
"url": https://b-site.com/show/123,
"site_id": 2
},
{
"host_name": "C 사이트",
"url": "https://c-site.com/show/123",
"site_id": 3
}
]
}
최종본은 다음과 같다.
그럼 Mongodb에 넣을 때 어떤 값을 기준으로 중복으로 처리하였는가?
우리는 티켓 데이터를 저장하는 것이었는데, 공연명으로만 기준을 잡기엔 재개봉하는 공연도 있을 것이고 이는 같은 데이터가 아니라 엄연히 다른 데이터로 처리해야 한다. 왜냐하면 공연일자가 다르기 때문!!
따라서, 우리가 쓴 방식은....
1. 공연명에서 공백과 특수기호를 모두 제거
2. "Duplicatekey" 라는 컬럼을 새로 만들어 1번에 처리한 값과 start_date 값을 붙인다.
3. 그럼 Duplicatekey: 뮤지컬시카고2024.01.01 과 같은 데이터가 담긴다.
따라서, 그 컬럼값을 기준으로 중복데이터를 구별한다.
중복처리하는 나의 코드는 다음과 같다. (참고문서)
# 중복된 데이터가 존재하는지 체크
existing_data = db.ticket.find_one({"duplicatekey": duplicate_key})
if existing_data is None:
# 중복된 데이터가 없으면 새로운 데이터 삽입
try:
print(f"Inserting new data: {duplicate_key}")
db.ticket.insert_one({
"title": original_title,
"duplicatekey": duplicate_key,
"category": category,
"location": performance_place,
"price": price_info,
"start_date": start_date,
"end_date": end_date,
"running_time": running_time,
"casting": None,
"rating": age_rating,
"description": final_description,
"poster_url": poster_img,
"region": area,
"open_date": None,
"pre_open_date": None,
"artist": performer_info,
"hosts": [{"site_id": 2, "ticket_url":ticket_url}]
})
except DuplicateKeyError:
print(f"Duplicate key error: {duplicate_key}")
else:
# 이미 데이터가 존재하면 hosts 필드만 업데이트
print(f"Data already exists for {duplicate_key}. Updating hosts.")
previous_data = db.ticket.find_one({"duplicatekey":duplicate_key})
previous_data = previous_data["hosts"]
if len(previous_data) < 2:
previous_data.append({"site_id":2, "ticket_url":ticket_url})
db.ticket.update_one({"duplicatekey":duplicate_key},{"$set":{"hosts":previous_data}})
" if len(previous_data) < 2: "을 한 이유는 반복적으로 DB에 적재한다고 했을 때 이 데이터는 한 번만 들어가야하기에 previous_data의 길이가 2를 넘어서는 안되기 때문이다.
이렇게하면 중복데이터를 처리하면서 어떤 데이터에 여러 웹사이트에서 티켓을 판매하고 있는지 알 수 있다. 만약, 한 개의 웹사이트만 존재하는 경우는 <단독판매>로 구별할 수 있다.
'데이터엔지니어 부트캠프' 카테고리의 다른 글
데이터엔지니어 부트캠프 - 유사 공연 추천시스템 (23주차) (0) | 2024.12.22 |
---|---|
데이터엔지니어 부트캠프 - MongoDB jwt토큰 decode 하여 user_id 불러오기 (22주차) (1) | 2024.12.15 |
데이터엔지니어 부트캠프 - 로그데이터를 카프카를 이용해서 s3에 적재하기 (21주차) (1) | 2024.12.08 |
데이터엔지니어 부트캠프 - 에어플로우와 s3 연결하기 + mongodb 연결하기 (11월의 기록) (0) | 2024.12.01 |
데이터엔지니어 부트캠프 - Redis Cache로 에어플로우 배치돌렸을 때 마지막 번호부터 실행하게 하기 (20주차) (0) | 2024.12.01 |