CouchDB에서의 map-reduce change capture design


서론

원래는 부동산에 볼 일이 있어서 CouchDB로 찍먹하면서 이것저것 만들고 있었던 건데, 예상외의 사건이 터져서 부동산을 관두게 되었다. 따라서 원래 이 글도 구현까지 하면서 쓰려다가 다 망해버려서 원래 생각해뒀던 설계만 대충 끄적거리고 구현은 집어치우게 되었음을 양해 부탁드린다.

개요

간단히 말하자면 어떤 변경사항에 대해 해당 문서가 어떤 인덱스를 변경하는지 계산해서 해당 인덱스를 참조하는 aggregated value를 materialized derived view마냥 별도의 문서에 저장하겠다 이거다. 이렇게 하면 해당 문서를 참조하는 다른 문서를 또 만들수도 있고, 또 해당 문서들을 가지고 또다른 index를 만드는 등의 여러가지 활용이 가능할 거라고 생각했다.

대충의 설계

이게 되려면 먼저 문서의 변경사항에 대해 어떤 인덱스에 영향을 주는지 알아야 하는데, 이는 CouchDB의 mapper 함수를 돌려봐야 알 수 있는 일이다. CouchDB에서 구동하는 JS 엔진을 그대로 돌릴수야 없는 일이니 그냥 NodeJS의 vm으로 쓱 돌려봐야 한다. emit함수를 적당히 선언해서 돌려보면 된다.

이렇게 해서 인덱스에 어떤 Key/Value가 빠지고, 어떤 Key/Value가 추가되는지 확인하고 나면, 이를 바탕으로 인덱스에 해당하는 값들을 재계산해서 문서에 저장하면 된다. 하나의 Key가 여러개의 aggregated value에 영향을 줄 수 있으니 모든 가능한 aggregation을 모두 변경해줘야 한다…

결론

되긴 될 것 같은데, Range를 구체적으로 지정할 순 없을 것 같다. 예를 들자면,

[“A”, “B”] ~ [“B”, “C”] 까지의 범위를 참조하는 aggregated view같은건 바로는 못만들고,

[“A”]만 참조하는 aggregated view와 [“B”]만 참조하는 aggregated view를 따로 만든다음에 두 개의 view를 참조하는 새로운 문서를 만들고 거기서 view query를 수행해서 값을 계산하는 식으로 해야하는데, 아무래도 그때그때 쿼리를 실행하는 것보다 너무 번거로운 작업이 될 것 같아 구현까지 해 보기는 저어하게 되었다.