unique index가 걸린 컬렉션에 bulkWrite를 통해서 upsert를 하고 있었는데, E11000 duplicate key error가 떴다. 내가 작성한 코드는 다음과 같았는데, 주목해보면 filter 부분에 내가 집어넣으려는 모든 데이터가 들어있다.
tasks.append(UpdateOne(item, {"$set": item}, upsert=True))
Upsert는 다음과 같은 3개의 스텝으로 이루어진다.
1. filter에 따라 식별되는 도큐먼트를 찾는다.
2. 도큐먼트가 존재하면, 해당 도큐먼트를 atomic하게 업데이트한다.
3. 존재하지 않는다면, atomic하게 도큐먼트를 삽입한다.
나는 filter를 제대로 설정하지 않았다.
filter에는 중복값을 식별할 수 있을만한 최소의 데이터만 들어가야한다.
unique index에 game_id와 user_id라는 키가 걸려있다면 filter는 다음과 같이되어야한다.
{"game_id": item["game_id"], "user_id", item["user_id"}
제너럴하게 쓸 수 있는 라이브러리 형식으로 개발하고 있었기때문에 unique_keys 배열을 추가로 받아서 다음과 같이 해결했다.
filter_item = dict((key, item[key]) for key in option.get('unique_keys'))
tasks.append(UpdateOne(filter_item, {"$set": item}, upsert=True))
'프로그래밍 > NoSQL' 카테고리의 다른 글
[MongoDB] 인증 활성화: DB 사용자 추가 방법 (docker compose) (0) | 2022.07.14 |
---|