MongoDB에서 문서 간 집합 교차 구하기
MongoDB에서 단일 컬렉션에 저장된 여러 문서의 배열 필드 사이에 공통으로 존재하는 값을 찾고 싶다면 $setIntersection 연산자를 활용하면 됩니다. 이 연산자는 집계 파이프라인(aggregate) 안에서 두 개 이상의 배열을 입력받아, 모든 배열에 공통으로 포함된 요소만 반환합니다.
먼저 예제로 사용할 컬렉션과 문서를 생성해 보겠습니다.
> db.setInterSectionDemo.insertOne(
... {"_id":101, "Value1":[55,67,89]}
... );
{ "acknowledged" : true, "insertedId" : 101 }
> db.setInterSectionDemo.insertOne(
... {"_id":102, "Value2":[90,45,55]}
... );
{ "acknowledged" : true, "insertedId" : 102 }
> db.setInterSectionDemo.insertOne(
... {"_id":103, "Value3":[92,67,45]}
... );
{ "acknowledged" : true, "insertedId" : 103 }위 명령을 실행하면 세 개의 문서가 각각 다른 배열 필드(Value1, Value2, Value3)와 함께 삽입됩니다.
저장된 문서 확인하기
find() 메서드를 사용하면 컬렉션에 저장된 모든 문서를 조회할 수 있습니다.
> db.setInterSectionDemo.find().pretty();
실행 결과는 다음과 같습니다.
{ "_id" : 101, "Value1" : [ 55, 67, 89 ] }
{ "_id" : 102, "Value2" : [ 90, 45, 55 ] }
{ "_id" : 103, "Value3" : [ 92, 67, 45 ] }집계 파이프라인으로 교집합 계산하기
이제 _id가 101과 103인 두 문서의 배열 값 사이에서 공통 요소, 즉 교집합을 구해 보겠습니다. 전체 과정은 $match → $group → $project 세 단계로 진행됩니다.
> db.setInterSectionDemo.aggregate([
... {
... "$match": {
... "_id": { "$in": [101, 103] }
... }
... },
... {
... "$group": {
... "_id": 0,
... "firstValue": { "$first": "$Value1" },
... "secondValue": { "$last": "$Value3" }
... }
... },
... {
... "$project": {
... "firstValue": 1,
... "secondValue": 1,
... "CommonValue": { "$setIntersection": [ "$firstValue", "$secondValue" ] },
... "_id": 0
... }
... }
... ]);각 단계의 역할은 다음과 같습니다.
1. $match: _id가 101 또는 103인 문서만 필터링하여 다음 단계로 전달합니다.
2. $group: 모든 문서를 하나의 그룹으로 묶고, $first와 $last 연산자를 사용해 Value1과 Value3 배열을 각각 추출합니다.
3. $project: $setIntersection 연산자로 두 배열의 교집합을 계산하고, 불필요한 _id 필드는 제외한 뒤 결과를 출력합니다.
쿼리 실행 결과는 다음과 같습니다.
{ "firstValue" : [ 55, 67, 89 ], "secondValue" : [ 92, 67, 45 ], "CommonValue" : [ 67 ] }결과를 보면 첫 번째 배열 [55, 67, 89]과 두 번째 배열 [92, 67, 45] 사이에서 유일하게 공통된 값인 67이 CommonValue로 반환된 것을 확인할 수 있습니다. 이처럼 $setIntersection을 사용하면 복잡한 애플리케이션 로직 없이도 데이터베이스 차원에서 손쉽게 집합 연산을 처리할 수 있습니다.