MongoDB에서 특정 조건을 만족하는 문서만 필터링하면서 두 개의 필드 값을 연결(concatenate)해야 하는 경우가 있습니다. 이럴 때 $redact 연산자와 함께 $cond(조건문)와 $concat(문자열 연결)을 조합하면 간단하게 해결할 수 있습니다.
1. 샘플 컬렉션 생성
먼저 데모용 컬렉션을 만들고 문서를 삽입해 보겠습니다.
> db.demo745.insertOne({Value1:"100",Value2:"100"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5eae6419a930c785c834e554")
}
> db.demo745.insertOne({Value1:"40",Value2:"50"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5eae6421a930c785c834e555")
}
> db.demo745.insertOne({Value1:"13",Value2:"45"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5eae6429a930c785c834e556")
}2. 전체 문서 조회하기
find() 메서드를 사용하면 컬렉션의 모든 문서를 확인할 수 있습니다.
> db.demo745.find();
위 쿼리는 다음과 같은 결과를 출력합니다.
{ "_id" : ObjectId("5eae6419a930c785c834e554"), "Value1" : "100", "Value2" : "100" }
{ "_id" : ObjectId("5eae6421a930c785c834e555"), "Value1" : "40", "Value2" : "50" }
{ "_id" : ObjectId("5eae6429a930c785c834e556"), "Value1" : "13", "Value2" : "45" }3. 조건과 함께 문자열 연결하기
이제 $redact 안에서 $cond와 $concat을 사용하여, Value1과 Value2를 연결한 값이 "1345"와 일치하는 문서만 남기는 쿼리를 작성해 보겠습니다.
> db.demo745.aggregate(
... [
... { "$redact": {
... "$cond": [
... { "$eq": [
... { "$concat": [ "$Value1","$Value2" ] },
... "1345"
... ]},
... "$$KEEP",
... "$$PRUNE"
... ]
... }}
... ]
... )쿼리 동작 방식
- $concat: 각 문서의 Value1과 Value2 필드 값을 하나의 문자열로 연결합니다.
- $eq: 연결된 문자열이 "1345"와 같은지 비교합니다.
- $cond: 조건이 참이면 "$$KEEP"(문서 유지), 거짓이면 "$$PRUNE"(문서 제거)을 반환합니다.
위 집계 쿼리는 다음과 같은 결과를 출력합니다.
{ "_id" : ObjectId("5eae6429a930c785c834e556"), "Value1" : "13", "Value2" : "45" }결과를 보면 Value1("13")과 Value2("45")를 연결한 값이 "1345"와 일치하는 세 번째 문서만 필터링되어 반환된 것을 확인할 수 있습니다.
참고: $match와 $addFields를 사용한 대안
MongoDB 3.4 이상 버전에서는 $redact 대신 $addFields와 $match를 조합하는 방법도 있습니다. 가독성이 더 좋아 실무에서 자주 활용됩니다.
> db.demo745.aggregate([
... { $addFields: { combined: { $concat: [ "$Value1", "$Value2" ] } } },
... { $match: { combined: "1345" } }
... ])이처럼 MongoDB의 집계 파이프라인 연산자들을 적절히 조합하면 조건 기반 문자열 연결 및 필터링 작업을 손쉽게 처리할 수 있습니다.