본문 바로가기
MongoDB/MongoDB Atlas CRUD 다루기

MongoDB Atlas 클러스터(데이터베이스) access하기&CRUD하기 - 4. count_documents 관련 함수

by Fletcher 2024. 7. 28.

※ 참고자료 ※

PyMongo 4.8.0 Documentation Reference Link

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

 

 

 

반갑습니다!

저번 포스트에서 find_one()과 find() 함수를 살펴봤습니다

위 함수들은 해당 조건(filter)에 부합하는 도큐먼트들과

그 해당하는 도큐먼트들의 키-밸류 정보를 조회하는 함수였는데요

 

때로는 해당 도큐먼트의 구체적인 키-밸류 정보 말고,

해당 조건에 부합하는 도큐먼트가 총 몇 개인지 그 조회된 개수(count)만 필요한 때가 있죠?

 

오늘은 count_documents와 관련된 함수들을 알아보겠습니다 ^^

 

 

 

 

먼저, count_documents() 함수입니다

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

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

        # 다중 항목 조회
        result = collection.count_documents({})

        # 리소스 종료
        client.close()

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

 

이 함수는 두 가지로 사용할 수가 있는데요

파라미터 안에 아무런 조건을 넣어주지 않으면,

해당 컬렉션에 있는 총 도큐먼트의 수를 int 타입으로 반환해줍니다

 

 

 

 

해당 API 호출 결과 제가 지정한 데이터베이스의 콜렉션에는

도큐먼트가 총 26개가 있는 것으로 출력되었습니다

그럼 클러스터에 가서 한 번 확인해볼까요?

 

 

 

 

상기 이미지를 보시는 바와 같이,

제가 지정한 project-server 데이터베이스의 MongoDB_TEST 컬렉션에는

총 26개의 도큐먼트가 저장되어 있습니다!

 

해당 함수가 잘 작동해서 올바른 값을 리턴해줬음을 확인할 수 있겠습니다 ^^

 

 

 

 

 

그럼 이제 이 count_documents() 함수의 파라미터에 특정 조건(filter)을 넣어보겠습니다

이번 포스트를 위해서 별도의 더미 데이터들을 준비했는데요

여러 설명을 위해서 key-value를 다양하게 설정을 해놨습니다

 

다양한 조건들에 대한 샘플 코드를 차례대로 소개해드리겠습니다 ^^

 

 

 

※조건1 : 존재성 여부※

그 중에 "speciality"라는 키가 존재하는 도큐먼트만 한 번 조회해보겠습니다

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

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

        # 다중 항목 조회
        result = collection.count_documents({"speciality":{"$exists":True}})

        # 리소스 종료
        client.close()

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

 

기본적으로, 해당 조건을 count_documents() 함수의 파라미터 안에

중괄호({})로 감싸서 딕셔너리 형태로 넣어주시면 되는데요

 

조회하고자 하는 조건이란게 상황에 따라서 참 다양하죠?

 

만약 해당 키의 값을 특정 값으로 한정하는 것이 아니라,

도큐먼트 안에 해당 키가 존재하는 데이터만, 또는 해당 키가 존재하지 않는 데이터만 조회하고자 하는,

즉, 존재성 여부를 조건으로 걸어주고 싶다면 위 코드와 같이

{ "해당 키" : { "$exists" : True | False } }의 형태를 넣어주시면 되겠습니다

 

 

 

 

제 해당 컬렉션의 여러 더미 도큐먼트 중 "speciality"라는 키가 존재하는 도큐먼트는 단 두 개 뿐입니다

그럼 이제 포스트맨으로 호출해서 확인해보겠습니다

 

 

 

 

해당 코드가 정상적으로 작동하여 올바른 결과를 출력한 것을 확인할 수 있겠습니다 ^^

 

 

 

 

 

 

 

 

※조건2 : 범위 제한※

이번에는 "age"라는 키의 값 중 특정 범위를 만족하는 도큐먼트만 한 번 조회해보겠습니다

 

임의의 수에 대한 대소판별을 할 때 범위 조건이 네 가지가 있죠?

x ≥ y : x는 y보다 크거나 같다  →  "~ 이상"

x ≤ y : x는 y보다 작거나 같다  →  "~ 이하"

x > y : x는 y보다 크다  →  "~ 초과"

x < y : x는 y보다 작다 → "~ 미만"

 

그래서 이 조건들을 조합하면, 다음과 같은 중복 조건들도 만들 수가 있죠

ex1)   a   ≤   x <  b

x는 a 이상(크거나 같고) b 미만(작다)이다

ex2)    a  <  x   ≤   b

x는 a 초과(크고) b 이하(작거나 같다)이다

 

 

그럼 이 조건들에 대한 코드가 어떻게 되는지 샘플을 살펴보시겠습니다

 

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

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

        # 다중 항목 조회
        result = collection.count_documents({"age":{"$gte":20, "$lte":30}})     #case 1
        result = collection.count_documents({"age":{"$gt":20, "$lt":30}})     #case 2
        result = collection.count_documents({"age":{"$gt":20}})     #case 3
        result = collection.count_documents({"age":{"$lte":30}})     # case4

        # 리소스 종료
        client.close()

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

 

각 케이스에 대한 코드를 함께 첨부했습니다 ^^

여기서 보시면 아까와 같이 "해당 키"의 value로 여러 값들이 들어가있는데요

이해를 돕기 위해서 부연 설명을 곁들이겠습니다

 

① "$gte"

"greater than or equal to"의 축약 표현으로서,

"~보다 크거나 같다"는 조건입니다

 

 

② "$lte"

 "less than or equal to"의 축약 표현으로서,

"~보다 작거나 같다"는 조건입니다

 

"$gt"

"greater than"의 축약 표현으로서,

"~보다 크다"는 조건입니다

 

④ "$lt"

"less than"의 축약 표현으로서,

"~보다 작다"는 조건입니다

 

 

 

 

 

 

 

 

※조건3 : 특정 값 한정(일치)※

이번에는 "is_publish"라는 키의 값이 null인 조건을 만족하는 도큐먼트만 한 번 조회해보겠습니다

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

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

        # 다중 항목 조회
        result = collection.count_documents({"is_publish": None})

        # 리소스 종료
        client.close()

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

 

예시를 위해 준비한 데이터 중에서,

"is_publish" 키의 값이 null인 도큐먼트가 하나 존재하는데요

만약에 해당하는 데이터를 조회하려면 상기 코드와 같이

해당 키의 값을 None으로 설정해주시면 도큐먼트 중에서

해당 키의 값이 null을 만족하는 데이터만 조회해서 갯수에 대한 값을 가져옵니다 ^^

 

 

 

 

 

 

 

 

※조건4 : 특정 값 제외※

이번에는 조건을 여집합의 개념으로 한 번 접근해볼까요?

준비한 예시 도큐먼트 중에서 is_publish 값이 0인 값들이 있는데요

이 데이터들을 조회할 때 { "is_publish" : 0 }의 형태가 아니라,

"is_publish"의 값이 1이 아닌 데이터들을 조회하는 형태로 접근해보겠습니다 ^^

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

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

        # 다중 항목 조회
        result = collection.count_documents({"is_publish": {"$ne":1}})

        # 리소스 종료
        client.close()

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

 

조건 설정으로, 해당 키에 대한

value로 { "$ne" : 임의의 값 } 형태를 기입해주시면 되겠습니다 ^^

위 예시에서 조회하는 결과는 "is_publish" 키의 값이 1이 아닌 모든 도큐먼트가 되겠습니다

 

 

 

 

이번 포스트에서는 count_documents() 함수에 대해 살펴보면서

filter로 사용할 수 있는 조건들에 대해서 겸사겸사 알아보았습니다 ^^

 

이 조건들은 물론 count_documents() 뿐 아니라, 앞전에 같이 알아본

find()와 find_one() 함수에도 filter로 적용이 가능합니다!

 

다만 차이점은 해당 조건에 대한 결과를

count_documents() 함수의 경우에는 int 타입으로,

find_one() 함수는 dictionary 타입으로,

find() 함수는 Cursor 객체로 리턴을 해주죠 ^^

 

다음 포스트에서는 estimated_count_document() 함수와

distinct() 함수, 그리고 변경 사항에 대한 모니터링과 관련된 내용 하나를 함께 나누겠습니다

 

 

 

포스트 읽어주셔서 감사드리며, 즐겁고 뿌듯한 개발 되시기 바랍니다 ^.^