MongoDB Aggregate, 파이썬 연동

[Aggregation]

- Aggregation framework와 mapreduce가 제공

- RDBMS의 group by의 개념

- 집계작업이 단순한 경우에 mapreduce보다는 aggregation framework를 사용

- input으로 사용된 document를 처리하고 처리 결과로 output document를 생성하고

  생성된 output document를 또 다른 명령어의 input document로 활용

  = 이를 파이프라인(Pipeline)이라 한다.

- 파이프라인으로 집계를 처리하며 이 처리 명령을 배열로 나타낸다

 

 

1. Aggregation 연산자

$match : where절, having절과 같은 개념

$group : group by

$sort : order by

$sum : 총합, 총 갯수

         -----      -----------

  총합을 계산한 필드      1을 정의

$avg : 평균

$max : 최대값

 

2. 형식

db.컬렉션명.aggregate(aggregation연산들을 이용해서 명령어를 정의)

                ---------------------------------------------------------------

                   여러개를 사용하는 경우 배열로 표현

db.컬렉션명.aggregate([

                {$match:{조건...}},

                {$group:{필드명(_id):"$집계할 기준이 되는 필드",필드명(집어넣을 변수):{집계함수:집계할 필드명이나 값}}}])

 

문제)

- addr별 인원수를 구해라.

더보기

db.score.aggregate([{$group:{_id:"$addr", num:{$sum:1}}}])

같은 addr을 만날때마다 1을 더해준다.

select addr myaddr, count(id) num from score group by addr; - RDBMS로 표현

문제)

- dept별 인원수 구해라.

- dept별 java점수의 평균 구해라.

- addr별 servlet점수의 합계

더보기

db.score.aggregate([{$group:{_id:"$dept", sum:{$sum:1}}}])

db.score.aggregate([{$group:{_id:"$dept", avg:{$avg:"$java"}}}])

db.score.aggregate([{$group:{_id:"$addr", sum:{$sum:"$servlet"}}}])

문제) $match 사용하기

- dept별 java 점수가 80점 이상인 인원수를 구해라

더보기

db.score.aggregate([{$match:{java:{$gte:80}}},{$group:{_id:"$dept", num:{$sum:1}}}])

 

test.txt
0.00MB

텍스트파일에 든 명령어를 추가하고 문제를 풀어보자.

 

- 배열데이터가 있는 경우

favorites의 city배열에 서울과 인천이 존재하는 모든 document를 조회

db.test.find({"favorites.city":{$in:["서울","인천"]}})

 

- favorites의 city배열에 서울과 인천이 존재하고 java점수가 90점 이상인 모든 document를 조회

db.test.find({$and:[{"favorites.city":{$in:["서울","인천"]}},{java:{$gte:90}}]})

 

-쉬리 영화를 보거나 부서가 인사인 document 출력

db.test.find({$or:[{"favorites.movie":"쉬리"},{dept:"인사"}]})

 

- city가 부산,울산이면서 헬로카봇을 본 document 출력

db.test.find({$and:[{"favorites.city":{$in:["부산","울산"]}},{"favorites.movie":"헬로카봇"}]})

 

문제)

1. dept가 인사인 document의 servlet 평균 구하기

더보기

db.test.aggregate([{$group:{_id:"$dept", avg:{$avg:"$servlet"}}}])

2. java가 80점이 넘는 사람들의 부서별로 몇 명인지 구하기

더보기

db.test.aggregate([{$match:{java:{$gte:80}}},{$group:{_id:"$dept", num:{$sum:1}}}])

3. 2번 결과를 인원수 데이터를 내림차순으로 정렬해 보세요.

더보기

db.test.aggregate([{$match:{java:{$gte:80}}},{$group:{_id:"$dept", num:{$sum:1}}},{$sort:{num:1}}])

4. 앞에서 작업한 결과에 null인 document를 제외하세요

더보기

db.score.aggregate([{$match:{dept:{"$exists":true}}},{$group:{_id:"$dept", sum:{$sum:1}}}])

5. 다음과 같은 조건을 만족하는 document의 부서별 인원수를 구하세요

- 서울, 울산에 거주한 경험이 있고 헬로카봇을 본 적이 있다.

- java 점수가 80점 이상이다.

- 위 두 개의 조건을 모두 만족해야 한다.

더보기

db.test.aggregate([{$match:{$and:[{"favorites.city":{$in:["서울","울산"]}},{"favorites.movie":"헬로카봇"},{java:{$gte:80}}]}},{$group:{_id:"$dept", num:{$sum:1}}}])

6. 다음과 같은 조건을 만족하는 document 들의 부서별로 java의 평균을 구하세요

- 인천에 거주한 경험이 있거나 겨울왕국을 본 경험이 있다.

- java 점수가 90점 이상이다.

- 위 두 개의 조건은 둘 중에 하나만 만족하면 됩니다.

더보기

db.test.aggregate([{$match:{$and:[{java:{$gte:90}},{$or:[{"favorites.city":"인천"},{"favorites.movie":"겨울왕국"}]}]}},{$group:{_id:"$dept", avg:{$avg:"$java"}}}])

 


이제 어느정도 배웠으니 파이썬 연동을 해보자.

 

 

pymongo를 설치해주자.

 

그리고 mongo라는 python package 만들어주고 mongodb_connectino_test 파이썬 파일을 만들어주자.

 

import pymongo

# mongodb 서버에 접속해서 작업할 수 있도록 MongoClient객체를 생성
client = pymongo.MongoClient("mongodb://127.0.0.1:27017")

print(client.list_database_names()) #db 목록이 뜬다

이렇게 하면 db 목록이 뜬다.

 

그리고 mongodb 폴더를 만들고

그 안에 db파일이 저장된 폴더, log폴더, mongod.cfg파일을 만들어준다.

mongodb - db파일 저장된 폴더

              - log폴더

              - mongod.cfg 파일

 

log폴더 안에는 mongod.log 파일을 만들어줘서 로그 기록을 만들어줄것이다.

mongod.cfg파일을 메모장으로 열어서

 

dbpath=db파일 저장 폴더 경로
logpath=log폴더 경로\mongod.log
logappend=true
bind_ip=0.0.0.0
port=27017

를 적어서 저장해주자.

 

그리고 cmd를 열어서

 

mongod --config C:\2022_Iot\mongodb\mongod.cfg 실행하자.

그럼 어떤 창이 뜨는데 허용을 눌러주자.

이게 서버를 작동 시키는 것이다.

log폴더를 열어보면 log 텍스트 파일이 있을거다

이제 여기에 로그가 저장되어 있다.

 

 

이게 클라이언트로 접속을 해보자.

cmd를 열어서 mongo --host PC IP주소 --port 27017를 입력해주면 접속이 된다.

 

이제 파이참으로 돌아가서

import pymongo

# mongodb 서버에 접속해서 작업할 수 있도록 MongoClient객체를 생성
client = pymongo.MongoClient("mongodb://pc ip주소:27017")
#database접속

print(client.list_database_names()) #db 목록이 뜬다
db = client.get_database("sample") #database명시
#collection정보 확인
collections = db["score"]
print(db.list_collections_names()) #컬렉션 목록이 뜬다
print(collections) # 정보가 뜬다

입력해주면 주석과 같이 나오게 된다.

 

import pymongo

client = pymongo.MongoClient("mongodb://pc ip주소:27017")
#database접속
print(client.list_database_names())
db = client.get_database("sample")
myscore = db["score"] #score 콜렉션을 가져옴
#sample 데이터베이스의 score컬렉션에서 데이터 조회하기 - 1
result = db.score.find_one() #자동완성 불가
print(result)
#sample 데이터베이스의 score컬렉션에서 데이터 조회하기 - 2
result2 = myscore.find_one(); #자동완성 가능
print(result2)
import pymongo

client = pymongo.MongoClient("mongodb://pc ip주소:27017")
print(client.list_database_names())

db = client.get_database("sample")
myscore = db["score"]

#업데이트 처리하기
query = {"id":"jang"}
updatevalue = {"$set":{"name":"장길용"}}
myscore.update_many(query,updatevalue)
scorelist = myscore.find()
for mydoc in scorelist:
    print(mydoc)
    
#삭제 처리하기
result = myscore.delete_many({"dept":"총무"})
scorelist = myscore.find()
for mydoc in scorelist:
    print(mydoc)
    
#삽입 처리하기
my_dict = [{"name":"장동건","address":"서울"},
           {"name":"이민호","address":"제주"},
           {"name":"소지섭","address":"강원도"}]
x = myscore.insert_many(my_dict)
scorelist = myscore.find()
for mydoc in scorelist:
    print(mydoc)

 

 

문제)

1. MongoConnection

- 생성자에서 몽고디비 클라이언트를 통해 몽고디비서버에 접속할 수 있도록 합니다.

- getCollection

데이터베이스명과 컬렉션명을 입력받아 컬렉션 을 리턴하도록 작성합니다.

2. Board_Mongo

다음과 같은 조건을 만족할 수 있도록 메소드를 정의하세요

1) getBoardData()

- 게시판의 모든 데이터를 조회할 수 있도록 구현

2) getBoard

- 게시글 번호를 받아서 게시글을 조회할 수 있도록 작업하세요

- 매개변수 : 게시글번호

- 리턴값: 조회된 글

3) write

- 매개변수로 전달받은 데이터를 컬렉션에 저장할 수 있도록 작성합니다.

 

4) remove

매개변수로 전달받은 글 번호에 해당하는 게시글이 삭제되도록 작업합니다.

 

5) updateBoard

- 글의 타이틀이 수정되도록 작성합니다.

- 매개변수로 글 번호와 수정할 타이틀 내용을 입력받아 처리합니다.

 

6) search

- 매개변수로 입력된 문자열이 게시글과 타이틀에 포함된 게시글을 찾아 출력

- 매개변수는 검색어

3. board_test.py를 작성하시고

위의 6개의 메소드를 테스트하세요

 

import pymongo

class MyMongo():

    def __init__(self):
        self.client = pymongo.MongoClient("mongodb://192.168.50.201:27017")

    def getCollection(self,dbname,collection_name):
        db = self.client.get_database(dbname)
        self.doc = db[collection_name]
        return self.doc

    def getBoardData(self):
        dbPrint = self.doc.find()
        for mydoc in dbPrint:
            print(mydoc)

    def getBoard(self, num):
        for x in self.doc.find({"no":num}):
            pass
        return x

    def write(self, dict):
        self.doc.insert_many(dict)
        print("insert 완료")

    def remove(self, num):
        self.doc.delete_one({"no":num})
        print("remove 완료")

    def updateBoard(self, num, title):
        self.doc.update_one({"no":num},{"$set":{"content":title}})
        print("update 완료")

    def search(self, search_s):
        for x in self.doc.find({"content":{"$regex":search_s}}):
            print(x)

if __name__ == "__main__":
    obj = MyMongo()
    obj.getCollection("test","board")
    obj.getBoardData()
    print("--------------")
    print(obj.getBoard(1))
    my_dict = [{"no":6,"id":"dddd","content":"우와","writedate":"new Data()"}]
    obj.write(my_dict)
    print("--------------")
    obj.getBoardData()
    obj.remove(6)
    print("--------------")
    obj.getBoardData()
    obj.updateBoard(2,"이거 수정함")
    print(obj.getBoard(2))
    print("--------------")
    obj.search("사")

댓글

Designed by JB FACTORY