MongoDB Atlas 클러스터(데이터베이스) access하기&CRUD하기 - 6. update_one()
※ 참고자료 ※
PyMongo 4.8.0 Documentation Reference Link
https://pymongo.readthedocs.io/en/stable/index.html
반갑습니다!
저번 포스트까지 데이터 조회에 관련된 함수들을 살펴봤습니다
그 중에 변경 사항을 모니터링하는 부분에 대해서는,
이번 포스트에서 진행하는 update의 내용 이후에 살펴보기로 잠시 미뤄뒀었습니다
이제, 이번 포스트에서는 도큐먼트의 내용을 수정하는 방법에 대해서 알아보겠습니다
먼저는 update_one() 함수의 샘플 코드입니다
update_one() 함수의 파라미터에는 여러가지가 들어가는데요
positional하게 넣어주시려면,
첫 번째 자리는 filter 즉 해당 도큐먼트를 찾기 위한 조건입니다
그리고 두 번째 자리는 값을 변경하고자 하는 key-value를 기재해주시면 되겠습니다
위 샘플 코드를 풀어서 설명하면,
"
"project-server" 데이터베이스에 있는 "MongoDB_TEST" 컬렉션의 도큐먼트들 중에서
"name" 키의 값이 "Brandon Led"인 도큐먼트의 필드 중
"age" 키의 값을 66으로 바꿔라
"
라는 뜻이 되겠습니다
그리고 update_one() 함수를 시행하면 일정한 데이터를 리턴하는데요
① acknowledged : 작업이 성공적으로 수행되었는지 여부 의미
② matched_count : 필터 조건에 맞는 문서의 수 의미
③ modified_count : 수정된 문서의 수 의미
④ upserted_id : upsert 작업에서 생성된 새로운 문서의 _id 의미
현재 제 해당 컬렉션에는
"name":"Brandon Led" 조건을 만족하는 도큐먼트가 두 개가 있는데요
update_one() 함수를 사용하여 해당 조건과 데이터 갱신을 적용하면,
조건을 만족하는 모든 도큐먼트 중에서 최상단 1개의 도큐먼트에만
수정 내용이 반영됩니다 ^^
※ 참고 ※
update_one() 함수의 파라미터 종류
① filter
특정 문서를 찾기 위한 조건 → 해당 조건에 맞는 첫 번째 문서가 갱신됨
② update
갱신 데이터 지정 → $set, $inc 등이 사용됨
③ upsert
True로 설정하면, 해당 조건에 맞는 문서가 없을 경우 새로운 문서를 삽입함
(기본값: False)
④ array_filters
배열 필터를 적용하는 조건을 지정 → 배열 내 특정 요소를 갱신할 때 사용함
⑤ bypass_document_validation
True로 설정하면, 문서 유효성 검사를 무시함
(기본값: False)
⑥ collation
문자열 비교를 제어하기 위한 옵션
⑦ hint
인덱스 사용을 위한 힌트
⑧ session
특정 세션을 지정
그럼 포스트맨을 이용해서 한 번 시험동작하고 리턴 값을 확인 해보겠습니다
API 호출을 위해서 샘플 코드 중에서
json 요청 데이터를 받기 위해 data = request.get_json() 부분을 추가하고,
"$set"의 value로 data['age'] 부분만 추가로 수정한 다음 API 호출한 결과입니다
결과를 보니,
해당 Update 작업이 성공했고,
필터 조건에 맞는 도큐먼트는 1개였으며,
수정된 문서의 수는 1개였습니다!
여기서 upserted_id의 값은 null인데요
update_one() 함수의 파라미터로 upsert= True | False로 설정할 수 있습니다
default는 upsert = False이며,
True로 설정할 경우 해당 필터 조건에 만족하는 도큐먼트가 없을시 새로운 문서를 삽입하는 작업을 수행합니다
그 때 새로 생성된 도큐먼트의 아이디 값을 update의 리턴으로서 "upsert_id"로 반환합니다
그럼 이번엔 update_one() 함수의 파라미터 중 upsert를 True로 설정하여
해당 조건의 도큐먼트가 있으면 기존의 도큐먼트를 수정하고,
해당 조건의 도큐먼트가 없으면 새 도큐먼트를 삽입하는 작업을 해보겠습니다
아까의 샘플 코드를 조금만 변형해서 적용해보겠습니다
이 코드를 풀어서 설명하면,
"
"name" 키의 값이 "Brandon Led"인 도큐먼트를 찾아서,
"height" 필드의 값을 JSON 요청 데이터 중 height키의 값으로 갱신해라
"
가 되겠습니다
아까와 마찬가지로 성공적으로 처리가 되었습니다
filter 조건으로 지정한 것이, "name":"Brandon Led"였고,
해당 조건을 만족하는 기존의 도큐먼트가 존재했기 때문에
해당 도큐먼트의 필드로 "height":189라는 한 페어가
해당 도큐먼트의 새로운 필드로 추가되었을겁니다
한 번 확인을 해볼까요?
해당 도큐먼트에 "height"라는 필드가 존재하지 않았기 때문에
데이터가 추가되어 갱신된 것을 확인할 수 있겠습니다
여기서 잠깐,
MySQL 등과 같은 RDBMS와 다른 점이 바로 이 부분이죠
NoSQL은 스키마 구조에 대한 정형성이 없기 때문에
이렇게 새로운 필드가 추가 되는 것이 오류로 처리 되지 않고, 또 번거롭지도 않습니다
다시 본론으로 돌아와서,
그럼 이번에는 조건을 만족하는 도큐먼트가 없을 경우에
새로운 문서가 삽입되는 것도 확인해보겠습니다
현재 아래 코드의 조건을 만족하는 도큐먼트는 컬렉션에 존재하지 않습니다
어떤 형식으로 새로운 도큐먼트가 추가 되는지 한 번 확인해볼까요?
filter 조건으로 설정한 것과 수정 데이터의 값이 필드로 있는
새로운 도큐먼트가 추가된 것을 확인할 수가 있겠습니다 ^^
당연히 도큐먼트 고유의 id 값도 자동으로 지정이 되어있네요
마지막으로 한 가지 내용을 더 설명하고 마무리 짓도록 하겠습니다
filter를 적용할 때 배열 필터를 조건으로 적용할 수 있는데요
아래와 같은 예시 데이터를 준비했습니다
해당 도큐먼트의 필드는 "name"과 "grades" 두 개입니다
그리고 "grades"는 값으로 array를 갖는데
해당 어레이의 요소는 각각 {"subject":"math", "score":66}, {"subject":"korean", "score":98}입니다
아래 샘플과 같이 배열 필터를 이용해서 해당 조건을 조회한 다음 수정해보도록 하겠습니다
포스트맨으로 api를 호출한 결과 위와 같은 리스폰스를 받는 것을 볼 수가 있겠습니다
해당 조건을 만족하는 도큐먼트가 1개 있었고(matched_count),
해당 수정 내용이 반영된 도큐먼트가 총 1개가 되겠습니다(modified_count)
그리고 조건을 만족하는 도큐먼트가 기존에 존재했기 때문에
별도의 신규 도큐먼트가 생성되지 않았으므로 upserted_id는 당연히 None이 되겠습니다!
MongoDB Atlas의 클러스터를 확인해보니 상기 이미지와 같이
데이터 수정이 성공적으로 반영된 것을 확인할 수가 있겠습니다 ^^!
수정 전에는 66점이었는데 수정 후에는 88점이 되었습니다
이번 포스트에서는 update_one() 함수에 대해서
파라미터와 리턴 값들에 대해 알아보았습니다
여기서 줄이고 다음 포스트에서 이어서 찾아뵙겠습니다 ^^