MongoDB/MongoDB Atlas CRUD 다루기

MongoDB Atlas 클러스터(데이터베이스) access하기&CRUD하기 - 5. estimated_document_count(), distinct()

Fletcher 2024. 7. 28. 14:34

※ 참고자료 ※

PyMongo 4.8.0 Documentation Reference Link

https://pymongo.readthedocs.io/en/stable/index.html

 

 

 

반갑습니다!

저번 포스트에서 count_documents와 관련된 함수를 살펴봤습니다

해당 포스트에서, 조건(filter) 설정하는 방법과

그 조건에 부합하는 도큐먼트의 개수를 리턴하는 함수에 대해 알아보았습니다

 

오늘은 데이터 조회 마지막 시간으로,

count_documents()와 비슷한 estimated_document_count()와

distinct()와 변경 사항에 대한 모니터링 방법에 대해 알아보겠습니다

 

 

 

먼저, 두 함수의 차이점에 대해 살펴봐야겠는데요

① count_documents()

VS

② estimated_document_count()

 

간단히 정리하자면, estimated_document_count() 함수는

해당 컬렉션의 크기를 알기 위해 총 도큐먼트의 수를 "대략적으로" 추정하여 값을 반환해줍니다

인덱스를 사용하여 매우 빠르게 조회를 하는 것이 주요 특징 중에 하나입니다

 

근데, 여기서 잠깐 드는 생각이 있는데요.

분명히 저번 시간에 살펴보기를, count_documents() 함수에

별다른 필터를 지정하지 않으면 마찬가지로,

해당 컬렉션의 전체 도큐먼트 수를 리턴했습니다

 

굳이 번거롭게 똑같은 기능을 두 개의 함수로 만들어놓을 필요가 있을까요?

 

 

물론, 이 함수가

어마어마하게 큰 파급효과가 있는 핵심 기능이라거나 강력한 설정은 아닙니다

두 개를 비교해서 조금 더 살펴보면 차이가 느껴지는데요

 

먼저, estimated_document_count() 함수는 조건을 설정할 수 없습니다.

사용 목적은 항상 "컬렉션 크기 추정(=총 도큐먼트 수 파악)"이고,

완전히 딱 맞아떨어지는 정확한 파악이 아니고 대략적인 추산입니다.

 

때문에 하나하나 구체적으로 살필 필요가 없으므로,

인덱스를 사용해 빠르게 추정을 하므로 속도가 상대적으로 빠르죠.

이 속도 문제라는게 프로그래밍 세계에서 항상 거론되는 이야기인데,

느낌이 잘 안 오면 해당 사이즈를 몇 백만, 몇 천만, 몇 억, 몇 십억 단위로 키워보면

'속도'라는 성능과 효율성의 차이가 많이 체감이 됩니다

 

 

반대로 count_documents() 함수는 해당 조건을 만족하는 도큐먼트들을 정확히 조회하기 때문에

사용자가 임의의 조건을 설정해줄 수 있으며,

estimated_document_count() 보다는 느리겠지만,

특정 조건을 만족하는 도큐먼트들의 수에 대해 분명하고 신뢰할 수 있는 값을 리턴해주죠.

따라서 성능 부분에 대해서는 데이터베이스 크기와 인덱싱에 따라 다르며,

매우 큰 컬렉션의 경우 느릴 수도 있는 부분이 있습니다.

 

 

 

 

estimated_document_count() 함수와 관련된 샘플 코드입니다

#MongoDB Read - estimated_count_document() 테스트
class MongoDBEstimatedCountDocumentResource(Resource):
    def get(self):
        # 클러스터 접근을 위한 클라이언트 객체 생성
        client = pymongo.MongoClient(Config.MONGO_DB_URI)

        # 컬렉션 정보 저장
        database = client["project-server"]
        collection = database["MongoDB_TEST"]

        # 컬렉션 전체 크기 추정
        result = collection.estimated_document_count()

        # 리소스 종료
        client.close()

        return {"result":"success",
                "data":result}, 200

 

구조는 별다를 것이 없습니다.

estimated_document_count() 함수는 사용 목적이 한정적으로서 분명하기 때문에

조건을 설정 해줄 수 없으므로, 별도의 파라미터가 필요하지도 않습니다 ^^

 

"대략적"으로 추정을 해준다고 했는데, 이 "대략적"이란 표현이 어느정도인지

제가 샘플 데이터로 몇 백만, 몇 천만, 몇 억 건의 도큐먼트를 준비할 수는 없는 노릇인지라,

해당 컬렉션의 크기를 어떻게 추산해주는지 그 리턴 값만 한 번 확인해보겠습니다 ^^

 

 

 

현재 해당 컬렉션에는 26개의 도큐먼트가 존재합니다

굉장히 적은 수이기 때문에 정확하게 카운트 해주네요 ^^

 

 

 

 

 

 

 

 

 

 

다음으로는 이제 distinct() 함수를 알아보도록 하겠습니다

distinct() 함수는 이름에서부터 느껴지듯이, 어떤 값에 대해서 고유값들을 추출을 해주는 기능을 합니다

 

데이터베이스를 사용해서 데이터들을 저장하고 관리하다보면,

key에 대한 value들이 정말 천차만별이지만,

그 중에서도 중복되는 값들이 존재하기 마련이죠?

 

개발을 하다보면 필요와 목적에 따라서,

이 value들을 카테고리화 해서 고유값이 무엇무엇이 있는지 알아야 할 때가 종종 있습니다

MongoDB 환경에서는 그럴 때 이 distinct() 함수를 사용할 수가 있습니다

 

샘플 코드부터 한 번 살펴보실까요?

#MongoDB Read - distinct() 테스트
class MongoDBDistinctResource(Resource):
    def get(self):
        # 클러스터 접근을 위한 클라이언트 객체 생성
        client = pymongo.MongoClient(Config.MONGO_DB_URI)

        # 컬렉션 정보 저장
        database = client["project-server"]
        collection = database["MongoDB_TEST"]

        # 해당 키에 대한 밸류의 고유값 추출
        result = collection.distinct("is_publish")

        # 리소스 종료
        client.close()

        return {"result":"success",
                "data":result}, 200

 

distinct() 함수의 파라미터로 해당 컬렉션에 존재하는 키를 입력해주시면 되겠습니다

저는 도큐먼트들에 "is_publish"라는 키가 존재하는데요

이 키의 밸류를 카테고리화 해보면 0, 1, null이 중복되어 사용되었습니다

그럼 이 정보들을 제대로 조회해서 리턴해주는지 테스트를 한 번 해보겠습니다

 

 

 

 

Postman을 이용해 해당 테스트용 API를 호출해보니

위와 같은 결과를 리턴해주는데요

실제 컬렉션에 있는 사실 그대로,

"is_publish"라는 키의 value로 쓰인 null, 0, 1이라는 고윳값들을 컬렉션 타입으로 리턴해주네요 

 

 

 

 

 

여기서 한 발 더 나아가서,

해당 조건을 임의로 한정하도록 파라미터에 filter를 별도로 지정할 수 있을까요?

물론 가능합니다

 

이번에는 설명을 위해서 다른 조건을 한 번 이용해볼까요?

이번엔 "number"와 "is_publish" 키에 대해 중복조건을 설정해서

각각 value로 쓰인 고윳값들이 무엇이 있는지 확인해보겠습니다

 

#MongoDB Read - distinct() 테스트
class MongoDBDistinctResource(Resource):
    def get(self):
        # 클러스터 접근을 위한 클라이언트 객체 생성
        client = pymongo.MongoClient(Config.MONGO_DB_URI)

        # 컬렉션 정보 저장
        database = client["project-server"]
        collection = database["MongoDB_TEST"]

        # 해당 키에 대한 밸류의 고유값 추출
        result = collection.distinct( "number", {"is_publish":{"$ne":0}} )

        # 리소스 종료
        client.close()

        return {"result":"success",
                "data":result}, 200

 

distinct() 함수의 파라미터의 의미는 다음과 같습니다.

 

"

도큐먼트의 key-value pair 중에서

"number" 키의 value들 중 고윳값을 조회하되,

"is_publish" 키의 값이 0이 아닌 조건을 만족해야 한다.

"

 

해서 첫 번째 파라미터로 "해당 키",

두 번째 파라미터로 "해당 범위(제한 조건)"

을 삽입했습니다 ^^

 

 

 

그럼 이제 포스트맨을 통해 API를 호출해서 실제로 한 번 확인해보겠습니다

 

위와 같은 결과를 리턴했습니다.

제가 실제로 컬렉션에 저장한 정보들과 일치합니다

마찬가지로 리스트 타입으로 결과를 리턴해주네요 ^^

 

 

 

이상으로 두 가지를 살펴보았는데요.

CRUD 중 R에 해당하는 내용으로 한 가지가 더 있습니다.

바로 변경 사항에 대한 모니터링에 해당하는 부분인데요

 

이건 Update와 관련된 함수들을 살펴본 다음에 알아보도록 하겠습니다 ^^

 

 

오늘 포스트는 여기서 마무리 짓겠습니다

무더운 여름 개발하시느라 모든 개발자분들 수고가 많으십니다

늘 건승하시고 뿌듯함 느끼는 하루 되시기 바랍니다 ^.^