imhamburger 님의 블로그

데이터엔지니어 부트캠프 - MongoDB에 적재할 때 중복값 처리하기 본문

데이터엔지니어 부트캠프

데이터엔지니어 부트캠프 - MongoDB에 적재할 때 중복값 처리하기

imhamburger 2024. 12. 10. 14:50

파이널 프로젝트에서 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를 넘어서는 안되기 때문이다.

 

이렇게하면 중복데이터를 처리하면서 어떤 데이터에 여러 웹사이트에서 티켓을 판매하고 있는지 알 수 있다. 만약, 한 개의 웹사이트만 존재하는 경우는 <단독판매>로 구별할 수 있다.